Commit 9f987b1a authored by Mustafa Emre Acer's avatar Mustafa Emre Acer Committed by Commit Bot

[Lookalikes] Ignore signed exchange cache URLs if they are lookalikes

This CL detects and allows signed exchange cache URLs even if they are
lookalikes.

Signed Exchange cache URLs (the initial URL that redirects to the
SXG) serve application/signed-exchange Content-Type response header.
In this case, the navigation will always either fail or redirect to
the primary URL (getting the content either from inside the SXG or the
network depending on whether the validations succeed).

Bug: 1110151
Change-Id: I5a15c0248402e563bb34b9643c483d80770bd121
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2441276
Commit-Queue: Mustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatarJoe DeBlasio <jdeblasio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818052}
parent 8c487e7e
...@@ -30,6 +30,7 @@ LookalikeUrlBlockingPage::LookalikeUrlBlockingPage( ...@@ -30,6 +30,7 @@ LookalikeUrlBlockingPage::LookalikeUrlBlockingPage(
const GURL& request_url, const GURL& request_url,
ukm::SourceId source_id, ukm::SourceId source_id,
LookalikeUrlMatchType match_type, LookalikeUrlMatchType match_type,
bool is_signed_exchange,
std::unique_ptr< std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient> security_interstitials::SecurityInterstitialControllerClient>
controller_client) controller_client)
...@@ -39,7 +40,8 @@ LookalikeUrlBlockingPage::LookalikeUrlBlockingPage( ...@@ -39,7 +40,8 @@ LookalikeUrlBlockingPage::LookalikeUrlBlockingPage(
std::move(controller_client)), std::move(controller_client)),
safe_url_(safe_url), safe_url_(safe_url),
source_id_(source_id), source_id_(source_id),
match_type_(match_type) { match_type_(match_type),
is_signed_exchange_(is_signed_exchange) {
controller()->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW); controller()->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
controller()->metrics_helper()->RecordUserInteraction( controller()->metrics_helper()->RecordUserInteraction(
MetricsHelper::TOTAL_VISITS); MetricsHelper::TOTAL_VISITS);
......
...@@ -32,6 +32,7 @@ class LookalikeUrlBlockingPage ...@@ -32,6 +32,7 @@ class LookalikeUrlBlockingPage
const GURL& request_url, const GURL& request_url,
ukm::SourceId source_id, ukm::SourceId source_id,
LookalikeUrlMatchType match_type, LookalikeUrlMatchType match_type,
bool is_signed_exchange,
std::unique_ptr< std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient> security_interstitials::SecurityInterstitialControllerClient>
controller); controller);
...@@ -42,6 +43,8 @@ class LookalikeUrlBlockingPage ...@@ -42,6 +43,8 @@ class LookalikeUrlBlockingPage
security_interstitials::SecurityInterstitialPage::TypeID GetTypeForTesting() security_interstitials::SecurityInterstitialPage::TypeID GetTypeForTesting()
override; override;
bool is_signed_exchange_for_testing() const { return is_signed_exchange_; }
protected: protected:
// SecurityInterstitialPage implementation: // SecurityInterstitialPage implementation:
void CommandReceived(const std::string& command) override; void CommandReceived(const std::string& command) override;
...@@ -59,6 +62,9 @@ class LookalikeUrlBlockingPage ...@@ -59,6 +62,9 @@ class LookalikeUrlBlockingPage
const GURL safe_url_; const GURL safe_url_;
ukm::SourceId source_id_; ukm::SourceId source_id_;
LookalikeUrlMatchType match_type_; LookalikeUrlMatchType match_type_;
// True if the throttle encountered a response with
// is_signed_exchange_inner_response flag. Only checked in tests.
const bool is_signed_exchange_;
DISALLOW_COPY_AND_ASSIGN(LookalikeUrlBlockingPage); DISALLOW_COPY_AND_ASSIGN(LookalikeUrlBlockingPage);
}; };
......
...@@ -143,8 +143,9 @@ ThrottleCheckResult LookalikeUrlNavigationThrottle::ShowInterstitial( ...@@ -143,8 +143,9 @@ ThrottleCheckResult LookalikeUrlNavigationThrottle::ShowInterstitial(
web_contents, url, safe_url); web_contents, url, safe_url);
std::unique_ptr<LookalikeUrlBlockingPage> blocking_page( std::unique_ptr<LookalikeUrlBlockingPage> blocking_page(
new LookalikeUrlBlockingPage(web_contents, safe_url, url, source_id, new LookalikeUrlBlockingPage(
match_type, std::move(controller))); web_contents, safe_url, url, source_id, match_type,
handle->IsSignedExchangeInnerResponse(), std::move(controller)));
base::Optional<std::string> error_page_contents = base::Optional<std::string> error_page_contents =
blocking_page->GetHTMLContents(); blocking_page->GetHTMLContents();
...@@ -225,6 +226,28 @@ ThrottleCheckResult LookalikeUrlNavigationThrottle::PerformChecks( ...@@ -225,6 +226,28 @@ ThrottleCheckResult LookalikeUrlNavigationThrottle::PerformChecks(
first_is_lookalike = false; first_is_lookalike = false;
} }
// Allow signed exchange cache URLs such as
// https://example-com.site.test/package.sxg.
// Navigation throttles see signed exchanges as a redirect chain where
// Url 0: Cache URL (i.e. outer URL)
// Url 1: URL of the sgx package
// Url 2: Inner URL (the URL whose contents the sgx package contains)
//
// We want to allow lookalike cache URLs but not lookalike inner URLs, so we
// make an exception for this condition.
// TODO(meacer): Confirm that the assumption about cache URL being the 1st
// and inner URL being the last URL in the redirect chain is correct.
//
// Note that the signed exchange logic can still redirect the initial
// navigation to the fallback URL even if SGX checks fail (invalid cert,
// missing headers etc, see crbug.com/874323 for an example). Such navigations
// are not considered SGX navigations and IsSignedExchangeInnerResponse()
// will return false. We treat such navigations as simple redirects.
if (first_is_lookalike &&
navigation_handle()->IsSignedExchangeInnerResponse()) {
first_is_lookalike = false;
}
if (!first_is_lookalike && !last_is_lookalike) { if (!first_is_lookalike && !last_is_lookalike) {
return content::NavigationThrottle::PROCEED; return content::NavigationThrottle::PROCEED;
} }
......
...@@ -273,7 +273,7 @@ std::unique_ptr<LookalikeUrlBlockingPage> CreateLookalikeInterstitialPage( ...@@ -273,7 +273,7 @@ std::unique_ptr<LookalikeUrlBlockingPage> CreateLookalikeInterstitialPage(
} }
return std::make_unique<LookalikeUrlBlockingPage>( return std::make_unique<LookalikeUrlBlockingPage>(
web_contents, safe_url, request_url, ukm::kInvalidSourceId, web_contents, safe_url, request_url, ukm::kInvalidSourceId,
LookalikeUrlMatchType::kNone, LookalikeUrlMatchType::kNone, false,
std::make_unique<LookalikeUrlControllerClient>(web_contents, request_url, std::make_unique<LookalikeUrlControllerClient>(web_contents, request_url,
safe_url)); safe_url));
} }
......
...@@ -24,6 +24,11 @@ openssl ecparam -out prime256v1.key -name prime256v1 -genkey ...@@ -24,6 +24,11 @@ openssl ecparam -out prime256v1.key -name prime256v1 -genkey
openssl req -new -sha256 -key prime256v1.key -out prime256v1-sha256.csr \ openssl req -new -sha256 -key prime256v1.key -out prime256v1-sha256.csr \
-subj '/CN=test.example.org/O=Test/C=US' -subj '/CN=test.example.org/O=Test/C=US'
openssl req -new -sha256 -key prime256v1.key -out \
prime256v1-sha256-google-com.csr \
-subj '/CN=google-com.example.org/O=Test/C=US'
# Generate a certificate whose validity period starts at 2019-06-01 and # Generate a certificate whose validity period starts at 2019-06-01 and
# valid for 90 days. # valid for 90 days.
openssl ca -batch \ openssl ca -batch \
...@@ -34,6 +39,17 @@ openssl ca -batch \ ...@@ -34,6 +39,17 @@ openssl ca -batch \
-in prime256v1-sha256.csr \ -in prime256v1-sha256.csr \
-out prime256v1-sha256.public.pem -out prime256v1-sha256.public.pem
# Generate a certificate whose validity period starts at 2019-06-01 and
# valid for 90 days. Same as above, but for google-com.example.org.
openssl ca -batch \
-config google-com-ca.cnf \
-extensions sxg_cert \
-startdate 190601000000Z \
-enddate 190830000000Z \
-in prime256v1-sha256-google-com.csr \
-out prime256v1-sha256-google-com.public.pem
# Generate a certificate without CanSignHttpExchangesDraft extension. # Generate a certificate without CanSignHttpExchangesDraft extension.
openssl ca -batch \ openssl ca -batch \
-config ca.cnf \ -config ca.cnf \
......
...@@ -33,6 +33,11 @@ echo -n OCSP >$tmpdir/ocsp; echo -n SCT >$sctdir/dummy.sct ...@@ -33,6 +33,11 @@ echo -n OCSP >$tmpdir/ocsp; echo -n SCT >$sctdir/dummy.sct
gen-certurl -pem prime256v1-sha256.public.pem \ gen-certurl -pem prime256v1-sha256.public.pem \
-ocsp $tmpdir/ocsp -sctDir $sctdir > test.example.org.public.pem.cbor -ocsp $tmpdir/ocsp -sctDir $sctdir > test.example.org.public.pem.cbor
# Same as above, but for google-com.example.org.
gen-certurl -pem prime256v1-sha256-google-com.public.pem \
-ocsp $tmpdir/ocsp -sctDir $sctdir > google-com.example.org.public.pem.cbor
# Generate the certificate chain of "*.example.org", whose validity period is # Generate the certificate chain of "*.example.org", whose validity period is
# more than 90 days. # more than 90 days.
gen-certurl -pem prime256v1-sha256-validity-too-long.public.pem \ gen-certurl -pem prime256v1-sha256-validity-too-long.public.pem \
...@@ -72,8 +77,8 @@ gen-signedexchange \ ...@@ -72,8 +77,8 @@ gen-signedexchange \
-uri https://google-com.example.org/test/ \ -uri https://google-com.example.org/test/ \
-status 200 \ -status 200 \
-content test.html \ -content test.html \
-certificate prime256v1-sha256.public.pem \ -certificate prime256v1-sha256-google-com.public.pem \
-certUrl https://cert.example.org/cert.msg \ -certUrl https://google-com.example.org/cert.msg \
-validityUrl https://google-com.example.org/resource.validity.msg \ -validityUrl https://google-com.example.org/resource.validity.msg \
-privateKey prime256v1.key \ -privateKey prime256v1.key \
-date $signature_date \ -date $signature_date \
......
# This file is same as ca.cnf with the exception of subjectAltName field.
[ca]
default_ca = CA_root
preserve = yes
[CA_root]
dir = out
new_certs_dir = $dir
database = $dir/index.txt
serial = $dir/serial
certificate = ../../../../net/data/ssl/certificates/root_ca_cert.pem
private_key = ../../../../net/data/ssl/certificates/root_ca_cert.pem
default_md = sha256
unique_subject = no
policy = policy_anything
[sxg_cert]
basicConstraints = CA:FALSE
# OID required for sxg since d54c469
1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName=DNS:google-com.example.org
[policy_anything]
# Default signing policy
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional
HTTP/1.1 200 OK
Content-Type: application/cert-chain+cbor
-----BEGIN CERTIFICATE REQUEST-----
MIH4MIGfAgEAMD0xHzAdBgNVBAMMFmdvb2dsZS1jb20uZXhhbXBsZS5vcmcxDTAL
BgNVBAoMBFRlc3QxCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAElFfdVfWVnYyDSfXmIkjMokHtKd1SLpMcJiV1gzYsTABuyq5PUhaghqpelLbG
vTBUEYH8BupWh2DdIF01fR3Kw6AAMAoGCCqGSM49BAMCA0gAMEUCIQC4wI2Lo4CN
/8MDiD14faGKqizZZURk1wNln5qQ7ZhLngIgZ3XkkcNcemHTc5srzamFFNKJU2L3
zpJjorgaC+H3rn8=
-----END CERTIFICATE REQUEST-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
Validity
Not Before: Jun 1 00:00:00 2019 GMT
Not After : Aug 30 00:00:00 2019 GMT
Subject: CN=google-com.example.org, O=Test, C=US
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:94:57:dd:55:f5:95:9d:8c:83:49:f5:e6:22:48:
cc:a2:41:ed:29:dd:52:2e:93:1c:26:25:75:83:36:
2c:4c:00:6e:ca:ae:4f:52:16:a0:86:aa:5e:94:b6:
c6:bd:30:54:11:81:fc:06:ea:56:87:60:dd:20:5d:
35:7d:1d:ca:c3
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
1.3.6.1.4.1.11129.2.1.22:
..
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
CF:65:B9:9B:EE:0E:EC:8E:A6:B9:69:96:82:20:F4:F7:8B:8A:B2:FA
X509v3 Authority Key Identifier:
keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB
X509v3 Subject Alternative Name:
DNS:google-com.example.org
Signature Algorithm: sha256WithRSAEncryption
ae:16:c3:1d:a9:b1:53:86:22:ee:90:e6:07:e6:03:c1:a1:10:
79:98:32:d9:61:31:f2:27:5c:6a:a2:80:c6:0b:d1:40:16:06:
65:5e:b9:72:e1:77:e1:a9:02:bf:b9:18:56:8a:24:0f:b7:84:
94:d7:53:51:e6:9f:51:fd:7e:fe:d2:64:9e:73:d0:97:2d:2f:
ad:64:41:28:ef:9e:e7:86:ca:18:04:39:7d:7d:b1:9f:3c:20:
f4:44:5b:a0:d4:00:28:bf:8c:c2:50:c9:c8:5e:cf:d5:1c:37:
98:8e:2e:d8:81:71:43:79:77:60:6b:85:01:34:14:70:73:33:
1d:df:6e:2e:30:b5:99:ff:0c:ac:82:b5:23:c2:f4:8c:8a:e0:
53:f2:f4:3f:cb:18:78:3c:b3:f4:f9:41:e3:d4:83:75:24:c8:
b6:16:15:d7:36:d1:06:a3:9a:0b:59:6b:cd:e4:05:8e:25:d8:
1f:44:bf:30:20:3b:92:dd:66:74:3b:e6:d2:91:0c:5a:81:ac:
d1:9d:3f:9e:fe:cd:31:a0:36:40:58:6f:01:01:f5:9c:f7:ab:
81:91:3f:d3:f1:3c:29:a3:47:a0:60:71:55:86:8c:15:3e:9e:
0c:54:45:04:4c:10:33:36:09:c5:88:56:3a:8e:78:3b:dc:5d:
43:5a:cd:84
-----BEGIN CERTIFICATE-----
MIIC9jCCAd6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE5MDYwMTAw
MDAwMFoXDTE5MDgzMDAwMDAwMFowPTEfMB0GA1UEAwwWZ29vZ2xlLWNvbS5leGFt
cGxlLm9yZzENMAsGA1UECgwEVGVzdDELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIB
BggqhkjOPQMBBwNCAASUV91V9ZWdjINJ9eYiSMyiQe0p3VIukxwmJXWDNixMAG7K
rk9SFqCGql6Utsa9MFQRgfwG6laHYN0gXTV9HcrDo4GlMIGiMAkGA1UdEwQCMAAw
EAYKKwYBBAHWeQIBFgQCBQAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUF
BwMBMB0GA1UdDgQWBBTPZbmb7g7sjqa5aZaCIPT3i4qy+jAfBgNVHSMEGDAWgBSb
JguKmKm7HbkfHOMaQDPtjheIqzAhBgNVHREEGjAYghZnb29nbGUtY29tLmV4YW1w
bGUub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQCuFsMdqbFThiLukOYH5gPBoRB5mDLZ
YTHyJ1xqooDGC9FAFgZlXrly4XfhqQK/uRhWiiQPt4SU11NR5p9R/X7+0mSec9CX
LS+tZEEo757nhsoYBDl9fbGfPCD0RFug1AAov4zCUMnIXs/VHDeYji7YgXFDeXdg
a4UBNBRwczMd324uMLWZ/wysgrUjwvSMiuBT8vQ/yxh4PLP0+UHj1IN1JMi2FhXX
NtEGo5oLWWvN5AWOJdgfRL8wIDuS3WZ0O+bSkQxagazRnT+e/s0xoDZAWG8BAfWc
96uBkT/T8Twpo0egYHFVhowVPp4MVEUETBAzNgnFiFY6jng73F1DWs2E
-----END CERTIFICATE-----
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment