danidemi
danidemi

Reputation: 4696

Basic authentication through HTTPS reverse proxy works with curl, don't work with browser

In our GKE Kubernetes cluster we have a deployment running a pod with a third-party unmodifiable legacy application exposing an HTTP service (port :80) protected with based authentication. The cluster is exposed to the outside Internet through a GCP load balancer that takes care of terminating HTTPS connections.

When, from the Internet, I try to access the service using CURL, it works perfectly, I got an HTTP status 200.

curl -vvv 'https://username:[email protected]/admin'
*   Trying 34.107.254.133...
* Connected to portale-ambrogio-test.sigemi.cloud (34.107.254.133) port 443 (#0)
* found 129 certificates in /etc/ssl/certs/ca-certificates.crt
* found 516 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: *.sigemi.cloud (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: CN=*.sigemi.cloud
*        start date: Tue, 24 May 2022 00:00:00 GMT
*        expire date: Wed, 24 May 2023 23:59:59 GMT
*        issuer: C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Domain Validation Secure Server CA
*        compression: NULL
* ALPN, server accepted to use http/1.1
* Server auth using Basic with user 'username'
> GET /admin HTTP/1.1
> Host: portale-ambrogio-test.sigemi.cloud
> Authorization: Basic aR.......................==
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Ntrip-Version: Ntrip/2.0
< Access-Control-Allow-Origin: *
< Server: NTRIP BKG Caster/2.0.39
< Content-Type: text/html
< Date: Tue, 06 Sep 2022 15:53:09 GMT
< Via: 1.1 google
< Transfer-Encoding: chunked
< Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

When I access the same resource through the browser, it fails instead.

Edge dev tools showing dump of req and resp

Do you know why that could happen? I think it is something related to some security policy implemented by the browser but what?

[EDIT] Now with the browser I'm explicitly typing username and password in the authentication pop up to avoid the problem pointed out by @john-hanley

Upvotes: 0

Views: 640

Answers (2)

danidemi
danidemi

Reputation: 4696

The problem was caused by few facts.

  1. Our web application was not fully compliant with any of the HTTP specs (1.1, 2 and 3) regarding the name of the HTTP headers. In particular HTTP/1.1 states that header names should be considered case insensitive, while HTTP/2 and HTTP/3 states that headers should be lower case. Our application expected header names to be capitalized, so it always looked for the "Authentication" header.
  2. When modern browsers connect to an HTTP web server, they usually use HTTP/1.1 and in this case, they tend to capitalize header names, so browsers actually send a header which name is spelled "Authorization".
  3. However when modern browsers connect to HTTPS, they upgrade to HTTP/2 or HTTP/3 id supported by the web server. If they upgrade to such protocols, they obey it, so the send the authorization header in lower case, so "authorization".
  4. Our reverse proxy is provided by GCP, that indeed supports HTTP/3. So, when the browser connects to our GCP reverse proxy it switches to HTTP/3 and start sending lower case headers.
  5. The reverse proxy the forward the request to our application in lower case.
  6. And because of 1) the app is unable to authenticate.

Hope this report can help, because I spend a whole day trying to figure it out (and I actually learnt about HTTP/2 and HTTP/3).

The solution was obviously to fix our application and made it fully HTTP compliant.

Upvotes: 1

John Hanley
John Hanley

Reputation: 81336

The CLI curl is converting username:password from the URI into Authorization: Basic ....

Chrome stopped supporting URI credentials in the address bar after version 52. Internally, this is still supported via JavaScript.

Upvotes: 0

Related Questions