]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Added configuration parameters for maximum sizes of request headers,
authorwessels <>
Tue, 11 May 1999 01:33:20 +0000 (01:33 +0000)
committerwessels <>
Tue, 11 May 1999 01:33:20 +0000 (01:33 +0000)
request bodies, and reply bodies.  Added new error page (ERR_TOO_BIG).

Large request bodies can be detected immediately because the request
header must have a valid content length.

Large reply bodies can be detected either by the content-length reply
header, or if not present, by the number of bytes written to the
client.

src/cf.data.pre
src/client_side.cc
src/enums.h
src/structs.h

index 5508bba7c929eb5f9666bb8b85f11b2da6df9253..5a1e6f14990329d4471fc298cf12360ec6c79df8 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.152 1999/05/04 21:58:18 wessels Exp $
+# $Id: cf.data.pre,v 1.153 1999/05/10 19:33:20 wessels Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -1027,17 +1027,50 @@ wais_relay_port 8000
 DOC_END
 
 
-NAME: request_size
+NAME: request_header_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 10 KB
+LOC: Config.maxRequestHeaderSize
+DOC_START
+       This specifies the maximum size for HTTP headers in a request.
+       Request headers are usually relatively small (about 512 bytes).
+       Placing a limit on the request header size will catch certain
+       bugs (for example with persistent connections) and possibly
+       buffer-overflow or denial-of-service attacks.
+request_header_max_size 10 KB
+DOC_END
+
+NAME: request_body_max_size
 COMMENT: (KB)
 TYPE: b_size_t
 DEFAULT: 100 KB
-LOC: Config.maxRequestSize
+LOC: Config.maxRequestBodySize
 DOC_START
-       Maximum allowed request size in kilobytes.  If people are using
-       POST to upload files, then set this to the largest acceptable
-       filesize plus a few extra kbytes.
+       This specifies the maximum size for an HTTP request body.
+       In other words, the maximum size of a PUT/POST request.
+       A user who attempts to send a request with a body larger
+       than this limit receives an "Invalid Request" error message.
+       If you set this parameter to a zero, there will be no limit
+       imposed.
+request_body_max_size 100 KB
+DOC_END
 
-request_size 100 KB
+NAME: reply_body_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 0
+LOC: Config.maxReplyBodySize
+DOC_START
+       This specifies the maximum size for an HTTP reply body.
+       This can be used to restrict users from downloading very
+       large files.  If the reply headers include a content-length
+       value, then we can recognize large reply bodies early and
+       avoid downloading any of it.  If not, we will download as
+       much data up to this limit and then ungraciously terminate
+       the transfer.  If you set this parameter to zero, there
+       will be no limit imposed.
+reply_body_max_size 0
 DOC_END
 
 
index 24c93aebd08819993a50672e257e7462086586db..c226f0d8cb1e30b6c918996e4ae8a7e5ea834f19 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.451 1999/05/04 21:08:40 wessels Exp $
+ * $Id: client_side.cc,v 1.452 1999/05/10 19:33:22 wessels Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -92,6 +92,7 @@ static int clientHierarchical(clientHttpRequest * http);
 static int clientCheckContentLength(request_t * r);
 static int httpAcceptDefer(void);
 static log_type clientProcessRequest2(clientHttpRequest * http);
+static int clientReplyBodyTooLarge(int clen);
 
 static int
 checkAccelOnly(clientHttpRequest * http)
@@ -1513,6 +1514,18 @@ clientPackMoreRanges(clientHttpRequest * http, const char *buf, ssize_t size, Me
     return i->debt_size > 0;
 }
 
+static int
+clientReplyBodyTooLarge(int clen)
+{
+    if (0 == Config.maxReplyBodySize)
+       return 0;               /* disabled */
+    if (clen < 0)
+       return 0;               /* unknown */
+    if (clen > Config.maxReplyBodySize)
+       return 1;               /* too large */
+    return 0;
+}
+
 /*
  * accepts chunk of a http message in buf, parses prefix, filters headers and
  * such, writes processed message to the client's socket
@@ -1567,7 +1580,16 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
            }
        }
        rep = clientBuildReply(http, buf, size);
-       if (rep) {
+       if (clientReplyBodyTooLarge(rep->content_length)) {
+           ErrorState *err = errorCon(ERR_TOO_BIG, HTTP_FORBIDDEN);
+           err->request = requestLink(http->request);
+           storeUnregister(http->entry, http);
+           storeUnlockObject(http->entry);
+           http->entry = clientCreateStoreEntry(http, http->request->method,
+               null_request_flags);
+           errorAppendEntry(http->entry, err);
+           return;
+       } else if (rep) {
            body_size = size - rep->hdr_sz;
            assert(body_size >= 0);
            body_buf = buf + rep->hdr_sz;
@@ -1722,6 +1744,8 @@ clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *da
        } else {
            comm_close(fd);
        }
+    } else if (clientReplyBodyTooLarge((int) http->out.offset)) {
+       comm_close(fd);
     } else {
        /* More data will be coming from primary server; register with 
         * storage manager. */
@@ -2368,7 +2392,7 @@ clientReadRequest(int fd, void *data)
                break;
            }
            if (0 == clientCheckContentLength(request)) {
-               err = errorCon(ERR_INVALID_REQ, HTTP_LENGTH_REQUIRED);
+               err = errorCon(ERR_TOO_BIG, HTTP_LENGTH_REQUIRED);
                err->src_addr = conn->peer.sin_addr;
                err->request = requestLink(request);
                http->al.http.code = err->http_status;
@@ -2407,6 +2431,15 @@ clientReadRequest(int fd, void *data)
                 */
                if (request->body_sz < cont_len)
                    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+               if (cont_len > Config.maxRequestBodySize) {
+                   err = errorCon(ERR_INVALID_REQ,
+                       HTTP_REQUEST_ENTITY_TOO_LARGE);
+                   err->request = requestLink(request);
+                   http->entry = clientCreateStoreEntry(http,
+                       METHOD_NONE, null_request_flags);
+                   errorAppendEntry(http->entry, err);
+                   break;
+               }
            }
            clientAccessCheck(http);
            continue;           /* while offset > 0 */
@@ -2417,11 +2450,11 @@ clientReadRequest(int fd, void *data)
             */
            k = conn->in.size - 1 - conn->in.offset;
            if (k == 0) {
-               if (conn->in.offset >= Config.maxRequestSize) {
+               if (conn->in.offset >= Config.maxRequestHeaderSize) {
                    /* The request is too large to handle */
                    debug(33, 0) ("Request won't fit in buffer.\n");
-                   debug(33, 0) ("Config 'request_size'= %d bytes.\n",
-                       Config.maxRequestSize);
+                   debug(33, 0) ("Config 'request_header_max_size'= %d bytes.\n",
+                       Config.maxRequestHeaderSize);
                    debug(33, 0) ("This request = %d bytes.\n",
                        (int) conn->in.offset);
                    err = errorCon(ERR_INVALID_REQ, HTTP_REQUEST_ENTITY_TOO_LARGE);
index 8029cb4d733035fa1ff12bb56de7b951cbb0e143..36d6297cdfc6ff9b028bae13b0ad3e767b64b697 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.150 1999/05/03 21:55:01 wessels Exp $
+ * $Id: enums.h,v 1.151 1999/05/10 19:33:23 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -85,6 +85,7 @@ typedef enum {
     ERR_FTP_FORBIDDEN,
     ERR_FTP_UNAVAILABLE,
     ERR_ONLY_IF_CACHED_MISS,   /* failure to satisfy only-if-cached request */
+    ERR_TOO_BIG,
     ERR_MAX
 } err_type;
 
index 762694f78186f6e0b7ab838a55f03c36140ccab1..7e032d95340265961e083f82f190c5758bd34f8b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.288 1999/05/04 20:49:39 wessels Exp $
+ * $Id: structs.h,v 1.289 1999/05/10 19:33:25 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -251,7 +251,9 @@ struct _SquidConfig {
        time_t ident;
 #endif
     } Timeout;
-    size_t maxRequestSize;
+    size_t maxRequestHeaderSize;
+    size_t maxRequestBodySize;
+    size_t maxReplyBodySize;
     struct {
        ushortlist *http;
        u_short icp;