J. K.(openbsd.l...@krottmayer.com) on 2021.10.21 14:10:16 +0200:
> Another question, to httpd(8). Tried the following query.
> Used an invalid HTTP Version number (typo).
> 
> $ telnet 10.42.42.183 80
> [Shortened]
> GET / HTTP/1.2
> [content]
> 
> httpd provide here the site. Without checking the not existent version
> (1.2) number and the Host. Okay, that's maybe stupid from me to
> start a request with an invalid version number. But should not also
> the server answer with 400 (bad request)?
> 
> According to the source only HTTP/1.1 is checked. All other request
> will be accepted. Okay, I'm not a RFC specialist. Still a newbie.

This diff makes httpd return "505 HTTP Version Not Supported"
for < 0.9 and > 1.9 http versions. Anything from 1.1 to 1.9 is
interpreted as 1.1. This is what nginx does too.

ok?

diff --git usr.sbin/httpd/server_http.c usr.sbin/httpd/server_http.c
index 6a74f3e45c5..52aaf3711c2 100644
--- usr.sbin/httpd/server_http.c
+++ usr.sbin/httpd/server_http.c
@@ -51,6 +51,7 @@ int            server_http_authenticate(struct server_config 
*,
                    struct client *);
 char           *server_expand_http(struct client *, const char *,
                    char *, size_t);
+int             http_version_num(char *);
 
 static struct http_method       http_methods[] = HTTP_METHODS;
 static struct http_error        http_errors[] = HTTP_ERRORS;
@@ -198,6 +199,19 @@ done:
        return (ret);
 }
 
+int http_version_num(char *version)
+{
+       if (strcmp(version, "HTTP/0.9") == 0)
+               return (9);
+       if (strcmp(version, "HTTP/1.0") == 0)
+               return (10);
+       /* any other version 1.x gets downgraded to 1.1 */
+       if (strncmp(version, "HTTP/1", 6) == 0)
+               return (11);
+
+       return (0);
+}
+
 void
 server_read_http(struct bufferevent *bev, void *arg)
 {
@@ -207,6 +221,7 @@ server_read_http(struct bufferevent *bev, void *arg)
        char                    *line = NULL, *key, *value;
        const char              *errstr;
        size_t                   size, linelen;
+       int                      version;
        struct kv               *hdr = NULL;
 
        getmonotime(&clt->clt_tv_last);
@@ -329,12 +344,29 @@ server_read_http(struct bufferevent *bev, void *arg)
                                *desc->http_query++ = '\0';
 
                        /*
-                        * Have to allocate the strings because they could
+                        * We have to allocate the strings because they could
                         * be changed independently by the filters later.
+                        * Allow HTTP version 0.9 to 1.1.
+                        * Downgrade http version > 1.1 <= 1.9 to version 1.1.
+                        * Return HTTP Version Not Supported for anything else.
                         */
-                       if ((desc->http_version =
-                           strdup(desc->http_version)) == NULL)
-                               goto fail;
+
+                       version = http_version_num(desc->http_version);
+                       if (version == 11) {
+                               if ((desc->http_version =
+                                   strdup("HTTP/1.1")) == NULL)
+                                       goto fail;
+                       } else {
+                               if ((desc->http_version =
+                                   strdup(desc->http_version)) == NULL)
+                                       goto fail;
+                       }
+
+                       if (version == 0) {
+                               server_abort_http(clt, 505, "bad http version");
+                               goto abort;
+                       }
+
 
                        if (desc->http_query != NULL &&
                            (desc->http_query =

Reply via email to