Skip to content

Commit

Permalink
Optionally limit the URI length.
Browse files Browse the repository at this point in the history
New listener configuration directive MaxURI sets the maximum allowed
length of an URI.

* NEWS: Document changes.
* doc/pound.8: Likewise.
* doc/pound.texi: Likewise.

* src/config.c (http_parsetab, https_parsetab): New statement: MaxURI.
* src/pound.h (max_req): Rename to max_req_size. All uses changed.
New field: max_uri_length.
* src/http.c (do_http): Optionally check if URI length is OK.

* tests/maxuri.at: New testcase.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Add new testcase.
  • Loading branch information
graygnuorg committed Mar 30, 2024
1 parent f6e4068 commit b56e958
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 9 deletions.
7 changes: 6 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Pound -- history of user-visible changes. 2024-03-29
Pound -- history of user-visible changes. 2024-03-30
See the end of file for copying conditions.

Pound is a continuation of the software originally developed by
Expand Down Expand Up @@ -46,6 +46,11 @@ Err400 - Err503 statements used in previous versions. These
statements are still supported for backward compatibility, although
their use is discouraged.

* New statement: MaxURI

This statement sets the maximum allowed length of the request URI.
It can be used in ListenHTTP and ListenHTTPS sections.

* Bugfixes

** Don't try to access the include directory, unless needed by configuration.
Expand Down
6 changes: 5 additions & 1 deletion doc/pound.8
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with pound. If not, see <http://www.gnu.org/licenses/>.
.TH POUND 8 "March 28, 2024" "pound" "System Manager's Manual"
.TH POUND 8 "March 30, 2024" "pound" "System Manager's Manual"
.SH NAME
pound \- HTTP/HTTPS reverse-proxy and load-balancer
.SH SYNOPSIS
Expand Down Expand Up @@ -889,6 +889,10 @@ Maximum allowed size of incoming request. All requests will be limited
to these many bytes. If a request contains more data than allowed, an
error 413 is returned. Default: unlimited.
.TP
\fBMaxURI\fR \fIn\fR
Maximum allowed length of an URI. If the URI of a request is longer than
\fIn\fR bytes, an error 414 is returned. Default: unlimited.
.TP
\fBRewriteLocation\fR 0|1|2
If set to 1, force
.B pound
Expand Down
8 changes: 8 additions & 0 deletions doc/pound.texi
Original file line number Diff line number Diff line change
Expand Up @@ -2503,6 +2503,14 @@ A request bigger than that will be responded with status
By default, there is no limit on the request size.
@end deffn

@deffn {ListenHTTP directive} MaxURI @var{n}
Limits the maximum allowed length of incoming request URI.
A request with an URI longer than that will be responded with status
414.

By default, there is no limit on the URI length.
@end deffn

@deffn {ListenHTTP directive} CheckURL "@var{pattern}"
Define a pattern that must be matched by each request sent to this
listener. A request that does not match will be returned a 501
Expand Down
7 changes: 4 additions & 3 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -4028,8 +4028,8 @@ static PARSER_TABLE http_parsetab[] = {
{ "Client", assign_timeout, NULL, offsetof (LISTENER, to) },
{ "CheckURL", listener_parse_checkurl },
{ "ErrorFile", parse_errorfile, NULL, offsetof (LISTENER, http_err) },
{ "MaxRequest", assign_CONTENT_LENGTH, NULL, offsetof (LISTENER, max_req) },

{ "MaxRequest", assign_CONTENT_LENGTH, NULL, offsetof (LISTENER, max_req_size) },
{ "MaxURI", assign_unsigned, NULL, offsetof (LISTENER, max_uri_length) },
{ "Rewrite", parse_rewrite, NULL, offsetof (LISTENER, rewrite) },
{ "SetHeader", SETFN_SVC_NAME (set_header), NULL, offsetof (LISTENER, rewrite) },
{ "DeleteHeader", SETFN_SVC_NAME (delete_header), NULL, offsetof (LISTENER, rewrite) },
Expand Down Expand Up @@ -4681,7 +4681,8 @@ static PARSER_TABLE https_parsetab[] = {
{ "Client", assign_timeout, NULL, offsetof (LISTENER, to) },
{ "CheckURL", listener_parse_checkurl },
{ "ErrorFile", parse_errorfile, NULL, offsetof (LISTENER, http_err) },
{ "MaxRequest", assign_CONTENT_LENGTH, NULL, offsetof (LISTENER, max_req) },
{ "MaxRequest", assign_CONTENT_LENGTH, NULL, offsetof (LISTENER, max_req_size) },
{ "MaxURI", assign_unsigned, NULL, offsetof (LISTENER, max_uri_length) },

{ "Rewrite", parse_rewrite, NULL, offsetof (LISTENER, rewrite) },
{ "SetHeader", SETFN_SVC_NAME (set_header), NULL, offsetof (LISTENER, rewrite) },
Expand Down
31 changes: 28 additions & 3 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -4095,7 +4095,7 @@ send_to_backend (POUND_HTTP *phttp, int chunked, CONTENT_LENGTH content_length)
*/
int rc = copy_chunks (phttp->cl, phttp->be, NULL,
phttp->backend->be_type != BE_BACKEND,
phttp->lstn->max_req);
phttp->lstn->max_req_size);
if (rc != HTTP_STATUS_OK)
{
log_error (phttp, rc, errno, "error sending chunks");
Expand Down Expand Up @@ -4603,11 +4603,36 @@ do_http (POUND_HTTP *phttp)
}
}

if (phttp->lstn->max_uri_length > 0)
{
int rc;
char const *url;
rc = http_request_get_url (&phttp->request, &url);
if (rc == RETRIEVE_OK)
{
size_t urlen;
if ((urlen = strlen (url)) > phttp->lstn->max_uri_length)
{
log_error (phttp, HTTP_STATUS_URI_TOO_LONG, 0,
"URI too long: %zu bytes",
urlen);
http_err_reply (phttp, HTTP_STATUS_URI_TOO_LONG);
return;
}
}
else
{
log_error (phttp, HTTP_STATUS_INTERNAL_SERVER_ERROR, 0,
"can't get URL from the request (shouldn't happen)");
goto err;
}
}

/*
* possibly limited request size
*/
if (phttp->lstn->max_req > 0 && content_length > 0
&& content_length > phttp->lstn->max_req)
if (phttp->lstn->max_req_size > 0 && content_length > 0
&& content_length > phttp->lstn->max_req_size)
{
log_error (phttp, HTTP_STATUS_PAYLOAD_TOO_LARGE, 0,
"request too large: %"PRICLEN" bytes",
Expand Down
3 changes: 2 additions & 1 deletion src/pound.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,8 @@ typedef struct _listener
unsigned to; /* client time-out */
regex_t *url_pat; /* pattern to match the request URL against */
char *http_err[HTTP_STATUS_MAX]; /* error messages */
CONTENT_LENGTH max_req; /* max. request size */
CONTENT_LENGTH max_req_size; /* max. request size */
unsigned max_uri_length; /* max. URI length */
int rewr_loc; /* rewrite location response */
int rewr_dest; /* rewrite destination header */
int disabled; /* true if the listener is disabled */
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ TESTSUITE_AT = \
logsup.at\
lstset.at\
maxrequest.at\
maxuri.at\
multival.at\
nb.at\
not.at\
Expand Down
37 changes: 37 additions & 0 deletions tests/maxuri.at
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This file is part of pound testsuite. -*- autotest -*-
# Copyright (C) 2022-2024 Sergey Poznyakoff
#
# Pound is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Pound is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pound. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([MaxURI])
AT_KEYWORDS([maxuri])

PT_CHECK([ListenHTTP
MaxURI 8
Service
Backend
Address
Port
End
End
End
],
[GET /echo/file

end

414
end
])

AT_CLEANUP
1 change: 1 addition & 0 deletions tests/testsuite.at
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ m4_include([xhttp.at])
m4_include([checkurl.at])
m4_include([errfile.at])
m4_include([maxrequest.at])
m4_include([maxuri.at])
m4_include([rewriteloc.at])
m4_include([nb.at])
m4_include([chunked.at])
Expand Down

0 comments on commit b56e958

Please sign in to comment.