httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ruediger Pluem <rpl...@apache.org>
Subject Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c
Date Tue, 08 Nov 2016 19:39:09 GMT


On 11/04/2016 03:20 PM, wrowe@apache.org wrote:
> Author: wrowe
> Date: Fri Nov  4 14:20:16 2016
> New Revision: 1768036
> 
> URL: http://svn.apache.org/viewvc?rev=1768036&view=rev
> Log:
> Add an option to enforce stricter HTTP conformance
> 
> This is a first stab, the checks will likely have to be revised.
> For now, we check
> 
>  * if the request line contains control characters
>  * if the request uri has fragment or username/password
>  * that the request method is standard or registered with RegisterHttpMethod
>  * that the request protocol is of the form HTTP/[1-9]+.[0-9]+,
>    or missing for 0.9
>  * if there is garbage in the request line after the protocol
>  * if any request header contains control characters
>  * if any request header has an empty name
>  * for the host name in the URL or Host header:
>    - if an IPv4 dotted decimal address: Reject octal or hex values, require
>      exactly four parts
>    - if a DNS host name: Reject non-alphanumeric characters besides '.' and
>      '-'. As a side effect, this rejects multiple Host headers.
>  * if any response header contains control characters
>  * if any response header has an empty name
>  * that the Location response header (if present) has a valid scheme and is
>    absolute
> 
> If we have a host name both from the URL and the Host header, we replace the
> Host header with the value from the URL to enforce RFC conformance.
> 
> There is a log-only mode, but the loglevels of the logged messages need some
> thought/work. Currently, the  checks for incoming data log for 'core' and the
> checks for outgoing data log for 'http'. Maybe we need a way to configure the
> loglevels separately from the core/http loglevels.
> 
> change protocol number parsing in strict mode according to HTTPbis draft
> - only accept single digit version components
> - don't accept white-space after protocol specification
> 
> Clean up comment, fix log tags.
> Submitted by: sf
> Backports: r1426877, r1426879, r1426988, r1426992
> 
> 

> Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c?rev=1768036&r1=1768035&r2=1768036&view=diff
> ==============================================================================
> --- httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c (original)
> +++ httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c Fri Nov  4 14:20:16 2016

> @@ -1040,23 +1108,79 @@ static void check_serverpath(request_rec
>      }
>  }
>  
> +static APR_INLINE const char *construct_host_header(request_rec *r,
> +                                                    int is_v6literal)
> +{
> +    struct iovec iov[5];
> +    apr_size_t nvec = 0;
> +    /*
> +     * We cannot use ap_get_server_name/port here, because we must
> +     * ignore UseCanonicalName/Port.
> +     */
> +    if (is_v6literal) {
> +        iov[nvec].iov_base = "[";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +    }
> +    iov[nvec].iov_base = (void *)r->hostname;
> +    iov[nvec].iov_len = strlen(r->hostname);
> +    nvec++;
> +    if (is_v6literal) {
> +        iov[nvec].iov_base = "]";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +    }
> +    if (r->parsed_uri.port_str) {
> +        iov[nvec].iov_base = ":";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +        iov[nvec].iov_base = r->parsed_uri.port_str;
> +        iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
> +        nvec++;
> +    }
> +    return apr_pstrcatv(r->pool, iov, nvec, NULL);
> +}
>  
>  AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
>  {
> -    const char *host_header;
> +    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
> +    const char *host_header = apr_table_get(r->headers_in, "Host");
> +    int is_v6literal, have_hostname_from_url = 0;
>  
>      if (r->hostname) {
>          /*
>           * If there was a host part in the Request-URI, ignore the 'Host'
>           * header.
>           */
> -        fix_hostname(r, NULL);
> +        have_hostname_from_url = 1;
> +        is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
>      }
> -    else if ((host_header = apr_table_get(r->headers_in, "Host")) != NULL ) {
> -        fix_hostname(r, host_header);
> +    else if (host_header != NULL) {
> +        is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
>      }
>      if (r->status != HTTP_OK)
>          return;
> +
> +    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
> +        /*
> +         * If we have both hostname from an absoluteURI and a Host header,
> +         * we must ignore the Host header (RFC 2616 5.2).
> +         * To enforce this, we reset the Host header to the value from the
> +         * request line.
> +         */
> +        if (have_hostname_from_url && host_header != NULL) {
> +            const char *info = "Would replace";
> +            const char *new = construct_host_header(r, is_v6literal);
> +            if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
> +                apr_table_set(r->headers_in, "Host", r->hostname);

Hm, why don't we use "new" here instead of r->hostname

> +                info = "Replacing";
> +            }
> +            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
> +                          "%s Host header '%s' with host from request uri: "
> +                          "'%s'", info, host_header, new);
> +        }
> +    }
> +
>      /* check if we tucked away a name_chain */
>      if (r->connection->vhost_lookup_data) {
>          if (r->hostname)
> 
> 
> 

Regards

RĂ¼diger


Mime
View raw message