From bdb2ae432689b2411258bb0508fa98f9df930af0 Mon Sep 17 00:00:00 2001 From: Nick Kew Date: Mon, 8 Sep 2008 14:20:11 +0000 Subject: [PATCH] Relax checks on HTTP Response status line from a backend. PR#44995 - Rainer Jung git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@693108 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ modules/http/http_filters.c | 19 ++++++++++++++----- modules/http/http_protocol.c | 30 +++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 0c862efc2b..ed02d2bdab 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.3.0 [ When backported to 2.2.x, remove entry from this file ] + *) Be tolerant in what you accept - accept slightly broken + status lines from a backend provide they include a valid status code. + PR 44995 [Rainer Jung + *) New module mod_sed: filter Request/Response bodies through sed [Basant Kumar Kukreja ] diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 5787c85a3a..7f6f9a5c9f 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -802,12 +802,21 @@ static void validate_status_line(request_rec *r) { char *end; - if (r->status_line - && (strlen(r->status_line) <= 4 + if (r->status_line) { + int len = strlen(r->status_line); + if (len < 3 || apr_strtoi64(r->status_line, &end, 10) != r->status - || *end != ' ' - || (end - 3) != r->status_line)) { - r->status_line = NULL; + || (end - 3) != r->status_line + || (len >= 4 && ! apr_isspace(r->status_line[3]))) { + r->status_line = NULL; + } + /* Since we passed the above check, we know that length three + * is equivalent to only a 3 digit numeric http status. + * RFC2616 mandates a trailing space, let's add it. + */ + else if (len == 3) { + r->status_line = apr_pstrcat(r->pool, r->status_line, " "); + } } } diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 0d1bee0ac3..37ac0e0c02 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -1232,16 +1232,28 @@ AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error) const char *h1; /* Accept a status_line set by a module, but only if it begins - * with the 3 digit status code + * with the correct 3 digit status code */ - if (r->status_line != NULL - && strlen(r->status_line) > 4 /* long enough */ - && apr_isdigit(r->status_line[0]) - && apr_isdigit(r->status_line[1]) - && apr_isdigit(r->status_line[2]) - && apr_isspace(r->status_line[3]) - && apr_isalnum(r->status_line[4])) { - title = r->status_line; + if (r->status_line) { + char *end; + int len = strlen(r->status_line); + if (len >= 3 + && apr_strtoi64(r->status_line, &end, 10) == r->status + && (end - 3) == r->status_line + && (len < 4 || apr_isspace(r->status_line[3])) + && (len < 5 || apr_isalnum(r->status_line[4]))) { + /* Since we passed the above check, we know that length three + * is equivalent to only a 3 digit numeric http status. + * RFC2616 mandates a trailing space, let's add it. + * If we have an empty reason phrase, we also add "Unknown Reason". + */ + if (len == 3) { + r->status_line = apr_pstrcat(r->pool, r->status_line, " Unknown Reason"); + } else if (len == 4) { + r->status_line = apr_pstrcat(r->pool, r->status_line, "Unknown Reason"); + } + title = r->status_line; + } } /* folks decided they didn't want the error code in the H1 text */ -- 2.40.0