Unverified Commit af32cd38 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

http: prevent custom Authorization headers in redirects

... unless CURLOPT_UNRESTRICTED_AUTH is set to allow them. This matches how
curl already handles Authorization headers created internally.

Note: this changes behavior slightly, for the sake of reducing mistakes.

Added test 317 and 318 to verify.

Reported-by: Craig de Stigter
Bug: https://curl.haxx.se/docs/adv_2018-b3bf.html
parent 993dd565
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
.\" *                            | (__| |_| |  _ <| |___
.\" *                             \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -77,6 +77,16 @@ the headers. They may be private or otherwise sensitive to leak.

Use \fICURLOPT_HEADEROPT(3)\fP to make the headers only get sent to where you
intend them to get sent.

Custom headers are sent in all requests done by the easy handles, which
implies that if you tell libcurl to follow redirects
(\fBCURLOPT_FOLLOWLOCATION(3)\fP), the same set of custom headers will be sent
in the subsequent request. Redirects can of course go to other hosts and thus
those servers will get all the contents of your custom headers too.

Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers
from being sent to other hosts than the first used one, unless specifically
permitted with the \fBCURLOPT_UNRESTRICTED_AUTH(3)\fP option.
.SH DEFAULT
NULL
.SH PROTOCOLS
+9 −1
Original line number Diff line number Diff line
@@ -714,7 +714,7 @@ Curl_http_output_auth(struct connectdata *conn,
  if(!data->state.this_is_a_follow ||
     conn->bits.netrc ||
     !data->state.first_host ||
     data->set.http_disable_hostname_check_before_authentication ||
     data->set.allow_auth_to_other_hosts ||
     strcasecompare(data->state.first_host, conn->host.name)) {
    result = output_auth_headers(conn, authhost, request, path, FALSE);
  }
@@ -1636,6 +1636,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
                  checkprefix("Transfer-Encoding:", headers->data))
            /* HTTP/2 doesn't support chunked requests */
            ;
          else if(checkprefix("Authorization:", headers->data) &&
                  /* be careful of sending this potentially sensitive header to
                     other hosts */
                  (data->state.this_is_a_follow &&
                   data->state.first_host &&
                   !data->set.allow_auth_to_other_hosts &&
                   !strcasecompare(data->state.first_host, conn->host.name)))
            ;
          else {
            CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
                                               headers->data);
+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
     * Send authentication (user+password) when following locations, even when
     * hostname changed.
     */
    data->set.http_disable_hostname_check_before_authentication =
    data->set.allow_auth_to_other_hosts =
      (0 != va_arg(param, long)) ? TRUE : FALSE;
    break;

+1 −1
Original line number Diff line number Diff line
@@ -1599,7 +1599,7 @@ struct UserDefined {
  bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
  bool http_follow_location; /* follow HTTP redirects */
  bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
  bool http_disable_hostname_check_before_authentication;
  bool allow_auth_to_other_hosts;
  bool include_header;   /* include received protocol headers in data output */
  bool http_set_referer; /* is a custom referer used */
  bool http_auto_referer; /* set "correct" referer when following location: */
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ test280 test281 test282 test283 test284 test285 test286 test287 test288 \
test289 test290 test291 test292 test293 test294 test295 test296 test297 \
test298 test299 test300 test301 test302 test303 test304 test305 test306 \
test307 test308 test309 test310 test311 test312 test313 test314 test315 \
test316                         test320 test321 test322 test323 test324 \
test316 test317 test318         test320 test321 test322 test323 test324 \
test325 \
test350 test351 test352 test353 test354 \
test393 test394 test395 \
Loading