Limit the body size in client requests (eg. POST data) to 1M by default;
authorreyk <reyk@openbsd.org>
Wed, 6 Aug 2014 18:21:14 +0000 (18:21 +0000)
committerreyk <reyk@openbsd.org>
Wed, 6 Aug 2014 18:21:14 +0000 (18:21 +0000)
add a configuration option to change the limit.

ok florian@

usr.sbin/httpd/config.c
usr.sbin/httpd/httpd.conf.5
usr.sbin/httpd/httpd.h
usr.sbin/httpd/parse.y
usr.sbin/httpd/server_http.c

index 95c80a8..7ab53b5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.20 2014/08/06 02:04:42 jsing Exp $       */
+/*     $OpenBSD: config.c,v 1.21 2014/08/06 18:21:14 reyk Exp $        */
 
 /*
  * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -296,6 +296,7 @@ config_getserver_config(struct httpd *env, struct server *srv,
                memcpy(&srv_conf->timeout, &srv->srv_conf.timeout,
                    sizeof(srv_conf->timeout));
                srv_conf->maxrequests = srv->srv_conf.maxrequests;
+               srv_conf->maxrequestbody = srv->srv_conf.maxrequestbody;
 
                DPRINTF("%s: %s %d location \"%s\", "
                    "parent \"%s\", flags: %s",
index adacb8d..d0c9194 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: httpd.conf.5,v 1.27 2014/08/06 16:31:09 jsing Exp $
+.\"    $OpenBSD: httpd.conf.5,v 1.28 2014/08/06 18:21:14 reyk Exp $
 .\"
 .\" Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
 .\"
@@ -123,6 +123,11 @@ and include one or more lines of the following syntax:
 Set the specified options and limits for HTTP connections.
 Valid options are:
 .Bl -tag -width Ds
+.It Ic max request body Ar number
+Set the maximum body size in bytes that the client can send to the server.
+The default value is
+.Ar 1048576
+bytes (1M).
 .It Ic max requests Ar number
 Set the maximum number of requests per persistent HTTP connection.
 Persistent connections are negotiated using the Keep-Alive header in
index c129860..74d6904 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: httpd.h,v 1.50 2014/08/06 16:09:02 jsing Exp $        */
+/*     $OpenBSD: httpd.h,v 1.51 2014/08/06 18:21:14 reyk Exp $ */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -50,6 +50,7 @@
 #define SERVER_MAXPROC         32
 #define SERVER_MAXHEADERLENGTH 8192
 #define SERVER_MAXREQUESTS     100     /* max requests per connection */
+#define SERVER_MAXREQUESTBODY  1048576 /* 1M */
 #define SERVER_BACKLOG         10
 #define SERVER_OUTOF_FD_RETRIES        5
 
@@ -370,6 +371,7 @@ struct server_config {
        int                      prefixlen;
        struct timeval           timeout;
        u_int32_t                maxrequests;
+       size_t                   maxrequestbody;
 
        char                    *ssl_cert;
        off_t                    ssl_cert_len;
index 2f74bb4..532e56a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.32 2014/08/06 16:11:34 jsing Exp $        */
+/*     $OpenBSD: parse.y,v 1.33 2014/08/06 18:21:14 reyk Exp $ */
 
 /*
  * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -125,10 +125,10 @@ typedef struct {
 
 %}
 
-%token ACCESS AUTO BACKLOG BUFFER CERTIFICATE CHROOT CIPHERS COMMON COMBINED
-%token CONNECTION DIRECTORY ERR FCGI INDEX IP KEY LISTEN LOCATION LOG MAXIMUM
-%token NO NODELAY ON PORT PREFORK REQUESTS ROOT SACK SERVER SOCKET SSL STYLE
-%token SYSLOG TCP TIMEOUT TYPES
+%token ACCESS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON
+%token COMBINED CONNECTION DIRECTORY ERR FCGI INDEX IP KEY LISTEN LOCATION
+%token LOG MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS ROOT SACK
+%token SERVER SOCKET SSL STYLE SYSLOG TCP TIMEOUT TYPES
 %token ERROR INCLUDE
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
@@ -231,6 +231,7 @@ server              : SERVER STRING         {
                        s->srv_conf.id = ++last_server_id;
                        s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT;
                        s->srv_conf.maxrequests = SERVER_MAXREQUESTS;
+                       s->srv_conf.maxrequestbody = SERVER_MAXREQUESTBODY;
                        s->srv_conf.flags |= SRVFLAG_LOG;
                        s->srv_conf.logformat = LOG_FORMAT_COMMON;
                        if ((s->srv_conf.ssl_cert_file =
@@ -473,6 +474,9 @@ conflags    : TIMEOUT timeout               {
                | MAXIMUM REQUESTS NUMBER       {
                        srv_conf->maxrequests = $3;
                }
+               | MAXIMUM REQUEST BODY NUMBER   {
+                       srv_conf->maxrequestbody = $4;
+               }
                ;
 
 ssl            : '{' sslopts_l '}'
@@ -793,6 +797,7 @@ lookup(char *s)
                { "access",             ACCESS },
                { "auto",               AUTO },
                { "backlog",            BACKLOG },
+               { "body",               BODY },
                { "buffer",             BUFFER },
                { "certificate",        CERTIFICATE },
                { "chroot",             CHROOT },
@@ -816,6 +821,7 @@ lookup(char *s)
                { "on",                 ON },
                { "port",               PORT },
                { "prefork",            PREFORK },
+               { "request",            REQUEST },
                { "requests",           REQUESTS },
                { "root",               ROOT },
                { "sack",               SACK },
index f221e5a..259376d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: server_http.c,v 1.41 2014/08/06 15:08:04 florian Exp $        */
+/*     $OpenBSD: server_http.c,v 1.42 2014/08/06 18:21:14 reyk Exp $   */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -120,6 +120,7 @@ void
 server_read_http(struct bufferevent *bev, void *arg)
 {
        struct client           *clt = arg;
+       struct server_config    *srv_conf = clt->clt_srv_conf;
        struct http_descriptor  *desc = clt->clt_desc;
        struct evbuffer         *src = EVBUFFER_INPUT(bev);
        char                    *line = NULL, *key, *value;
@@ -261,6 +262,11 @@ server_read_http(struct bufferevent *bev, void *arg)
                                server_abort_http(clt, 500, errstr);
                                goto abort;
                        }
+                       if ((size_t)clt->clt_toread >
+                           srv_conf->maxrequestbody) {
+                               server_abort_http(clt, 413, NULL);
+                               goto abort;
+                       }
                }
 
                if (strcasecmp("Transfer-Encoding", key) == 0 &&