LibWeb/SecureContexts: Correct the 127.0.0.0/8 trustworthiness check

This previously checked whether the first octet was non-zero, treating
most IPv4 addresses (e.g. 183.189.143.11) as potentially trustworthy.

Match the first octet against 0x7f so only 127.0.0.0/8 is trusted.
This commit is contained in:
Luke Wilde 2026-05-31 19:09:20 +01:00 committed by Shannon Booth
parent a7b9ba5711
commit 6ddbff39c7
3 changed files with 63 additions and 1 deletions

View file

@ -33,7 +33,7 @@ Trustworthiness is_origin_potentially_trustworthy(URL::Origin const& origin)
// 4. If origins host matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
if (origin.host().has<IPv4Address>()) {
if ((origin.host().get<IPv4Address>().to_u32() & 0xff000000) != 0)
if ((origin.host().get<IPv4Address>().to_u32() & 0xff000000) == 0x7f000000)
return Trustworthiness::PotentiallyTrustworthy;
} else if (origin.host().has<IPv6Address>()) {
auto ipv6_address = origin.host().get<IPv6Address>();

View file

@ -14,6 +14,7 @@ set(TEST_SOURCES
TestMimeSniff.cpp
TestNumbers.cpp
TestRefCountedTreeNode.cpp
TestSecureContexts.cpp
TestSourceHighlighter.cpp
TestStrings.cpp
)
@ -27,6 +28,7 @@ ladybird_utility(css-tokenizer SOURCES css-tokenizer.cpp LIBS LibFileSystem LibM
target_link_libraries(TestContentBlocker PRIVATE LibURL)
target_link_libraries(TestControlMessageQueue PRIVATE LibSync)
target_link_libraries(TestFetchURL PRIVATE LibURL)
target_link_libraries(TestSecureContexts PRIVATE LibURL)
target_link_libraries(TestSourceHighlighter PRIVATE LibURL LibWebView)
if (NOT WIN32)

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2026, Luke Wilde <luke@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <LibURL/Parser.h>
#include <LibURL/URL.h>
#include <LibWeb/SecureContexts/AbstractOperations.h>
static bool is_potentially_trustworthy(StringView url_string)
{
auto url = URL::Parser::basic_parse(url_string);
VERIFY(url.has_value());
return Web::SecureContexts::is_url_potentially_trustworthy(*url) == Web::SecureContexts::Trustworthiness::PotentiallyTrustworthy;
}
TEST_CASE(ipv4_loopback_is_potentially_trustworthy)
{
EXPECT(is_potentially_trustworthy("http://127.0.0.1/"sv));
// The whole 127.0.0.0/8 block is loopback, not just 127.0.0.1.
EXPECT(is_potentially_trustworthy("http://127.0.0.2/"sv));
EXPECT(is_potentially_trustworthy("http://127.0.0.0/"sv));
EXPECT(is_potentially_trustworthy("http://127.255.255.255/"sv));
}
TEST_CASE(non_loopback_ipv4_is_not_potentially_trustworthy)
{
EXPECT(!is_potentially_trustworthy("http://8.8.8.8/"sv));
EXPECT(!is_potentially_trustworthy("http://1.1.1.1/"sv));
EXPECT(!is_potentially_trustworthy("http://192.168.1.1/"sv));
// A non-zero final octet of 127 must not be mistaken for the leading octet.
EXPECT(!is_potentially_trustworthy("http://8.8.8.127/"sv));
// Just outside 127.0.0.0/8 on either side.
EXPECT(!is_potentially_trustworthy("http://126.0.0.1/"sv));
EXPECT(!is_potentially_trustworthy("http://128.0.0.1/"sv));
}
TEST_CASE(ipv6_loopback_is_potentially_trustworthy)
{
EXPECT(is_potentially_trustworthy("http://[::1]/"sv));
EXPECT(!is_potentially_trustworthy("http://[::2]/"sv));
}
TEST_CASE(localhost_is_potentially_trustworthy)
{
EXPECT(is_potentially_trustworthy("http://localhost/"sv));
EXPECT(is_potentially_trustworthy("http://foo.localhost/"sv));
EXPECT(!is_potentially_trustworthy("http://example.com/"sv));
}
TEST_CASE(https_and_wss_are_potentially_trustworthy)
{
EXPECT(is_potentially_trustworthy("https://example.com/"sv));
EXPECT(is_potentially_trustworthy("wss://example.com/"sv));
EXPECT(!is_potentially_trustworthy("http://example.com/"sv));
EXPECT(!is_potentially_trustworthy("ws://example.com/"sv));
}