summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Rowe Jr <wrowe@apache.org>2016-08-18 22:26:53 +0200
committerWilliam A. Rowe Jr <wrowe@apache.org>2016-08-18 22:26:53 +0200
commitdc0d9fa11e66dc80ead856b6902db8d9c1e40dc7 (patch)
tree78ab4af6742bc3328680909d726085aeaca2967d
parentRemove unused typedef uthn_dbd_conf (diff)
downloadapache2-dc0d9fa11e66dc80ead856b6902db8d9c1e40dc7.tar.xz
apache2-dc0d9fa11e66dc80ead856b6902db8d9c1e40dc7.zip
Correct request header handling of whitespace with the new possible config of
HttpProtocolOptions Unsafe StrictWhitespace I have elected not to preserve any significance to excess whitespace in the now-deprecated obs-fold code path, that's certainly open for discussion. This can be reviewed by tweaking t/conf/extra.conf to switch Strict to Unsafe. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1756847 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--server/protocol.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/server/protocol.c b/server/protocol.c
index ed1ff100a6..094dc88a40 100644
--- a/server/protocol.c
+++ b/server/protocol.c
@@ -878,6 +878,7 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
char *tmp_field;
core_server_config *conf = ap_get_core_module_config(r->server->module_config);
int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
+ int strictspaces = (conf->http_whitespace == AP_HTTP_WHITESPACE_STRICT);
/*
* Read header lines until we get the empty separator line, a read error,
@@ -988,7 +989,7 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
}
memcpy(last_field + last_len, field, len +1); /* +1 for nul */
/* Replace obs-fold w/ SP per RFC 7230 3.2.4 */
- if (strict) {
+ if (strict || strictspaces) {
last_field[last_len] = ' ';
}
last_len += len;
@@ -1017,9 +1018,23 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
return;
}
- if (!strict) {
+ if (!strict)
+ {
/* Not Strict ('Unsafe' mode), using the legacy parser */
+ if (strictspaces && strpbrk(last_field, "\n\v\f\r")) {
+ r->status = HTTP_BAD_REQUEST;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03451)
+ "Request header presented bad whitespace "
+ "(disallowed by StrictWhitespace)");
+ return;
+ }
+ else {
+ char *ll = last_field;
+ while ((ll = strpbrk(ll, "\n\v\f\r")))
+ *(ll++) = ' ';
+ }
+
if (!(value = strchr(last_field, ':'))) { /* Find ':' or */
r->status = HTTP_BAD_REQUEST; /* abort bad request */
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00564)
@@ -1029,10 +1044,19 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
return;
}
- tmp_field = value - 1; /* last character of field-name */
+ /* last character of field-name */
+ tmp_field = value - (value > last_field ? 1 : 0);
*value++ = '\0'; /* NUL-terminate at colon */
+ if (strictspaces && strpbrk(last_field, " \t")) {
+ r->status = HTTP_BAD_REQUEST;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03452)
+ "Request header field name with whitespace "
+ "(disallowed by StrictWhitespace)");
+ return;
+ }
+
while (*value == ' ' || *value == '\t') {
++value; /* Skip to start of value */
}
@@ -1040,7 +1064,14 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
/* Strip LWS after field-name: */
while (tmp_field > last_field
&& (*tmp_field == ' ' || *tmp_field == '\t')) {
- *tmp_field-- = '\0';
+ *(tmp_field--) = '\0';
+ }
+
+ if (tmp_field == last_field) {
+ r->status = HTTP_BAD_REQUEST;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03453)
+ "Request header field name was empty");
+ return;
}
}
else /* Using strict RFC7230 parsing */