On Wed, Apr 28, 2021 at 08:18:47AM -0400, Dave Voutila wrote: > > Claudio Jeker writes: > > > Another thing to consider is that X-Forwarded headers should only be > > accepted from trusted sources. I don't think this particular usage of > > X-Forwarded-Proto is probelmatic. In the end for this particular case of > > redirect using a relative URL seems to be a better choice since it will > > preserve the host, port and proto from the original requests without any > > configuration magic. > > Here's a quick effort to test out the idea. Not sure I like it yet...but > figured this could help move discussion forward. (Not looking for an OK > yet as I doubt this config style is good yet.) > > Couple points: > * the srvflag bitmap is sort of at the semantic breaking point as a > uint32_t...hesitant to bump it to uint64_t just to allow better flag > groupings but that's a thought > > * not sure i like my config style...maybe (yet another) optional token > or two in the "auto index" pattern instead? > > Quick example config folks can test with. First `# cp -R /var/www /tmp` > and then stage some files there for your enjoyment. > > chroot "/tmp/www" > server "default" { > listen on * port 80 > directory { > auto index > relative redirects > } > } > > Example without "relative redirects": > > ~ $ curl -i localhost/bgplg > HTTP/1.0 301 Moved Permanently > Server: OpenBSD httpd > Connection: close > Content-Type: text/html > Content-Length: 510 > Location: http://localhost/bgplg/ > > With "relative redirects": > > ~ $ curl -i localhost/bgplg > HTTP/1.0 301 Moved Permanently > Server: OpenBSD httpd > Connection: close > Content-Type: text/html > Content-Length: 510 > Location: /bgplg/ >
To be honest I feel this is total overkill. This is an automatic redirect from /foo/bar to /foo/bar/ when accessing directories that have an index file or have auto index on. It is one very specific case of redirect that never changes the host, port or protocol. I see no reason why this can't default to a relative redirect (but using an absolute path). Are there clients in the wild that fail to handle such a redirect? > Index: usr.sbin/httpd/httpd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v > retrieving revision 1.156 > diff -u -p -r1.156 httpd.h > --- usr.sbin/httpd/httpd.h 20 Apr 2021 21:11:56 -0000 1.156 > +++ usr.sbin/httpd/httpd.h 28 Apr 2021 12:10:18 -0000 > @@ -392,6 +392,7 @@ SPLAY_HEAD(client_tree, client); > #define SRVFLAG_DEFAULT_TYPE 0x00800000 > #define SRVFLAG_PATH_REWRITE 0x01000000 > #define SRVFLAG_NO_PATH_REWRITE 0x02000000 > +#define SRVFLAG_RELATIVE_REDIR 0x04000000 > #define SRVFLAG_LOCATION_FOUND 0x40000000 > #define SRVFLAG_LOCATION_NOT_FOUND 0x80000000 > > @@ -401,7 +402,7 @@ SPLAY_HEAD(client_tree, client); > "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \ > "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \ > "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \ > - "\37LOCATION_FOUND\40LOCATION_NOT_FOUND" > + "\33RELATIVE_REDIR\37LOCATION_FOUND\40LOCATION_NOT_FOUND" > > #define TCPFLAG_NODELAY 0x01 > #define TCPFLAG_NNODELAY 0x02 > Index: usr.sbin/httpd/parse.y > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/parse.y,v > retrieving revision 1.125 > diff -u -p -r1.125 parse.y > --- usr.sbin/httpd/parse.y 10 Apr 2021 10:10:07 -0000 1.125 > +++ usr.sbin/httpd/parse.y 28 Apr 2021 12:10:18 -0000 > @@ -137,9 +137,10 @@ typedef struct { > %token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT > CIPHERS COMMON > %token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY > LIFETIME > %token LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON > PORT PREFORK > -%token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG > TCP TICKET > -%token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD > REQUEST > -%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE > +%token PROTOCOLS REDIRECTS RELATIVE REQUESTS ROOT SACK SERVER SOCKET > STRIP > +%token STYLE SYSLOG TCP TICKET TIMEOUT TLS TYPE TYPES HSTS MAXAGE > SUBDOMAINS > +%token DEFAULT PRELOAD REQUEST ERROR INCLUDE AUTHENTICATE WITH BLOCK > DROP > +%token RETURN PASS REWRITE > %token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT > %token <v.string> STRING > %token <v.number> NUMBER > @@ -1038,7 +1039,11 @@ dirflags : INDEX STRING { > srv_conf->flags &= ~SRVFLAG_AUTO_INDEX; > srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX; > } > - ; > + | RELATIVE REDIRECTS { > + srv_conf->flags &= ~SRVFLAG_RELATIVE_REDIR; > + srv_conf->flags |= SRVFLAG_RELATIVE_REDIR; > + } > + ; > > > logformat : LOG logflags > @@ -1425,6 +1430,8 @@ lookup(char *s) > { "prefork", PREFORK }, > { "preload", PRELOAD }, > { "protocols", PROTOCOLS }, > + { "redirects", REDIRECTS }, > + { "relative", RELATIVE }, > { "request", REQUEST }, > { "requests", REQUESTS }, > { "return", RETURN }, > Index: usr.sbin/httpd/server_file.c > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/server_file.c,v > retrieving revision 1.69 > diff -u -p -r1.69 server_file.c > --- usr.sbin/httpd/server_file.c 16 Mar 2021 06:44:14 -0000 1.69 > +++ usr.sbin/httpd/server_file.c 28 Apr 2021 12:10:18 -0000 > @@ -85,13 +85,17 @@ server_file_access(struct httpd *env, st > if (path[strlen(path) - 1] != '/') { > if ((encodedpath = url_encode(desc->http_path)) == NULL) > return (500); > - if (asprintf(&newpath, "http%s://%s%s/", > - srv_conf->flags & SRVFLAG_TLS ? "s" : "", > - desc->http_host, encodedpath) == -1) { > - free(encodedpath); > - return (500); > - } > + > + if (srv_conf->flags & SRVFLAG_RELATIVE_REDIR) > + ret = asprintf(&newpath, "%s/", encodedpath); > + else > + ret = asprintf(&newpath, "http%s://%s%s/", > + srv_conf->flags & SRVFLAG_TLS ? "s" : "", > + desc->http_host, encodedpath); > + > free(encodedpath); > + if (ret < 0) > + return (500); > > /* Path alias will be used for the redirection */ > desc->http_path_alias = newpath; > -- :wq Claudio