Repository navigation
fix(security): stop reporting User-Agent versions as IP addresses - #168
Conversation
Chromium's reduced User-Agent reports every version as <major>.0.0.0, so Chrome/140.0.0.0 matched the ip_addresses PII pattern in any skill that documents or sets a browser User-Agent. Treat an IPv4-shaped value as a version when it has that <major>.0.0.0 shape and a product token sits directly before its slash. A .0.0.0 value is never a host address, so real IPs after a slash (paths, labels, URL paths) stay reported. Signed-off-by: Jeremy Levartovsky <[email protected]>
rng1995
left a comment
There was a problem hiding this comment.
Hi @JayOfTheKeyboard, thank you for this contribution, and for the careful report in #167! The before/after table, the "Not changed" notes, and the mutation results made this easy to review.
The fix is small and sits in the right place, next to the package-artifact rule in _is_version_literal. The new tests follow the conventions of their neighbors in TestSpdxAndIpFalsePositiveHardening. Here's what I checked locally on 7152e05:
- All 356 tests in
tests/validators/test_security.pypass, andruff check src testsis clean. - I reproduced your three mutations. Dropping the
.0.0.0shape check fails 5 guards, dropping the product-token check failsAllow 52.0.0.0 ..., and moving the rule below the network-word check fails thebase_urlcase. - A few more real-world UA forms are now clean: Edge desktop (
... Safari/537.36 Edg/140.0.0.0), Android Chrome,CriOS/140.0.0.0,Electron/38.0.0 Chrome/140.0.0.0, a Pythonheaders = {'User-Agent': ...}dict, andcurl -A '...'. URL authorities (https://52.0.0.0/,http://140.0.0.0:8080/path),YaBrowser/24.12.1.712, andcidr: 52.0.0.0/8are still reported, as intended.
I've left three small inline suggestions, none of them blocking:
- Pin which IP the mixed-line guard reports. As written, it also passes on
main. - Keep CIDR blocks that follow a slash reported, since a UA version is never followed by
/. - Optionally, handle JSON-escaped slashes (
Chrome\/140.0.0.0). This would also be fine as a follow-up.
Thanks again for tracking this down!
…lashes Review follow-up for NVIDIA#168: - a reduced UA version is never followed by '/', so allowlist/52.0.0.0/8 and URL paths ending in a CIDR block are reported again; - Chrome\/140.0.0.0 (JSON with escaped slashes) is treated like Chrome/140.0.0.0; - the mixed-line guard moves to its own test that pins the reported value to 8.8.8.8, since the any() form also passed on main. Signed-off-by: Jeremy Levartovsky <[email protected]>
|
Thanks for the careful review. All three suggestions are in 8c310c0:
The three new cases failed on 7152e05 before the change. All 359 tests in |
Signed-off-by: Jeremy Levartovsky <[email protected]>
rng1995
left a comment
There was a problem hiding this comment.
Thanks, @JayOfTheKeyboard, for the quick and thorough follow-up! All three suggestions are addressed in 8c310c0, and the CHANGELOG.md conflict from the merge with main is resolved cleanly, with both entries kept.
What I checked on d809322:
- The mixed-line case now has its own test that pins the reported value to
8.8.8.8. allowlist/52.0.0.0/8andhttps://api.example.com/v1/ips/52.0.0.0/8are reported again, and both are guard cases.- JSON-escaped
Chrome\/140.0.0.0is suppressed, whileBackups\/8.8.8.8is still reported. - All three new cases fail on 7152e05 and pass here.
- All 414 tests in
test_security.py,test_pii_grouping.pyandtest_security_validators.pypass, andruff check src testsis clean.
Approving. Thanks again for the fix!
Fixes #167.
Summary
The PII scan reports Chromium User-Agent versions as public IP addresses. Since Chrome 101, the reduced User-Agent writes every version as
<major>.0.0.0, soChrome/140.0.0.0matches theip_addressespattern. Onmainata2636b2:SKILL.mdUser-Agent: Mozilla/5.0 (X11; Linux x86_64) ... Chrome/140.0.0.0 Safari/537.36[PII-MEDIUM] Non-RFC1918 IP address: 140.0.0.0HeadlessChrome/151.0.0.0 -> Chrome/151.0.0.0Edge reports `Edg/140.0.0.0` and Opera reports OPR/122.0.0.0.page = browser.new_page(user_agent='Chrome/140.0.0.0', base_url=base)Backups/8.8.8.8,whitelist: Office/52.14.1.9,Proxy/8.8.8.8Chrome/140.0.0.0 through proxy 8.8.8.88.8.8.8)Allow 52.0.0.0 through the firewall._is_version_literaltreats an IPv4-shaped match as a version when both of these hold:\d{1,3}\.0\.0\.0;[A-Za-z][A-Za-z0-9]*) sits directly before its/.A
.0.0.0value is never a host address, so the rule cannot hide a real host after a slash. My first version keyed on the product token alone. An independent review found it hidBackups/8.8.8.8,Office/52.14.1.9and$HOME/8.8.8.8, and requiring the value's shape closed all three. The check sits next to the package-artifact rule, before the network-word check. That way a User-Agent that shares a line withbase_urlorproxyis still recognised, while URL authorities (https://52.0.0.0/) are still reported.Not changed
Chrome/140.0.7339.80were never IPv4-shaped. Four-part versions from other browsers with non-zero components, for exampleYaBrowser/24.12.1.712, are still reported. Covering them would need a list of browser names, and I left that to you.Chrome 140.0.0.0with a space and no slash is still reported. It is not User-Agent syntax.Verification
test_user_agent_product_versions_are_not_pii(4 cases) andtest_ip_outside_a_reduced_user_agent_version_remains_pii(7 guard cases) intests/validators/test_security.py. All 4 positive cases fail on the parent and pass with the fix; the 7 guards pass on both. Mutations, each separately: dropping the.0.0.0shape check turns 5 guards red, dropping the product-token check turnsAllow 52.0.0.0 ...red, and moving the rule after the network-word check turns thebase_urlcase red.make lint: passedmake test: with-n 6, 6,324 passed, 49 skipped and 588 failed. All 582 failures seen on pristinea2636b2in the same run also fail there. They are Harbor Tier 3 staging tests that fail on this host withstaging tree has unexpected or missing entries. The other 6 (Bedrock preflight and a DNS-deadline test) pass when rerun serially. The full suite is not claimed greenmake build: sdist and wheel builtReal-tool check:
skillevaluator pii-scanon the skill from #167 reports nothing after the fix. So does a browser-automation skill of mine whose docstring was the original trigger.Release Impact
CHANGELOG.md