Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions tests/test_share_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,29 @@ def git(*args):
assert check_share_safety.check_changed(base) == [
check_share_safety.Finding("candidate.txt", 3, "NON_DOCUMENTATION_IPV4")
]


def test_scope_operators_are_not_read_as_ipv6_addresses():
"""`Foo::bar` matches the IPv6 pattern and parses as an address in
::/8. Reserved blocks are not assignable to a host, so an address in
one cannot be the leak this rule exists to catch."""
colons = 2 * chr(58)
for text in (
"the leaf's `TbsCertificate" + colons + "signature_alg` is unparseable",
"see `std" + colons + "vector` and `Face" + colons + "expressRequest`",
"0" + colons + "1 is the discard prefix",
):
assert check_share_safety.scan_text("doc.md", text) == []


def test_host_assignable_ipv6_addresses_are_still_flagged():
colons = 2 * chr(58)
for text in (
"fe80" + colons + "1", # link-local
"fd00" + colons + "1", # unique-local
"2400" + chr(58) + "cb00" + colons + "1", # global unicast
):
findings = check_share_safety.scan_text("doc.md", text)
assert [finding.rule_id for finding in findings] == [
"NON_DOCUMENTATION_IPV6"
], text
12 changes: 11 additions & 1 deletion tools/check_share_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,17 @@ def _safe_ipv4(value: str) -> bool:
def _safe_ipv6(value: str) -> bool:
address = ipaddress.ip_address(value.strip("[]").split("%", 1)[0])
return (
address.is_loopback or address.is_unspecified or address in DOCUMENTATION_IPV6
address.is_loopback
or address.is_unspecified
or address in DOCUMENTATION_IPV6
# An address in an IETF-reserved block is not assignable to a host,
# so it cannot be the leak this rule exists to catch. Excluding them
# also clears a false positive on C++ and Rust scope operators: a
# scope operator preceded by a hex letter matches IPV6_RE, parses as
# an address in the all-zero reserved block, and is nobody's device.
# Global unicast, link-local and unique-local all sit outside the
# reserved set and stay flagged; see the tests for each.
or address.is_reserved
)


Expand Down