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/
-dv
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;