Summary
urlPatternToRegex() (duplicated in scripts/content.js and options/options.js) appends a hard $ end-anchor to any non-wildcard pattern. This makes an allowlisted host match only the bare root URL, never a real navigated deep link. An admin who allowlists the exact host of a page can still see that page scanned/blocked, because the actual URL includes a path.
Affected code
// Add end anchor if pattern doesn't end with wildcard
if (!pattern.endsWith("*") && !escaped.endsWith(".*")) {
escaped = escaped + "$";
}
Worked example
Allowlist entry: https://client.my.salesforce-setup.com/
Produced regex: ^https://client\.my\.salesforce-setup\.com/$
Tested URL (real deep link): https://client.my.salesforce-setup.com/lightning/setup/...
Result: no match. The trailing $ sits immediately after the /, so only the bare root URL matches. The admin allowlisted the exact host, including the protocol-qualified form, yet checkUserUrlAllowlist() returns false and the page-level early-exit never fires.
Scope of this fix (agreed)
Minimal: relax only the trailing anchoring so a host or root URL pattern (with or without a trailing slash) also matches an optional trailing path, query, or fragment. This does not add leading protocol or subdomain tolerance, so bare-domain entries such as five9.com still require the documented https://.../ * form. That broader behavior is intentionally out of scope here.
Expected behavior
https://host/ and https://host match https://host, https://host/, and https://host/any/deep/link.
- Suffix and prefix tricks must not match. For example
https://host.evil.com/ must not be matched by an allow entry for https://host/.
- Existing wildcard patterns (
https://google.com/*) and raw regex patterns (^https://login\.microsoftonline\.com$) are unchanged.
Notes
The two copies of urlPatternToRegex in content.js and options.js must stay in sync.
Summary
urlPatternToRegex()(duplicated inscripts/content.jsandoptions/options.js) appends a hard$end-anchor to any non-wildcard pattern. This makes an allowlisted host match only the bare root URL, never a real navigated deep link. An admin who allowlists the exact host of a page can still see that page scanned/blocked, because the actual URL includes a path.Affected code
Worked example
Allowlist entry:
https://client.my.salesforce-setup.com/Produced regex:
^https://client\.my\.salesforce-setup\.com/$Tested URL (real deep link):
https://client.my.salesforce-setup.com/lightning/setup/...Result: no match. The trailing
$sits immediately after the/, so only the bare root URL matches. The admin allowlisted the exact host, including the protocol-qualified form, yetcheckUserUrlAllowlist()returns false and the page-level early-exit never fires.Scope of this fix (agreed)
Minimal: relax only the trailing anchoring so a host or root URL pattern (with or without a trailing slash) also matches an optional trailing path, query, or fragment. This does not add leading protocol or subdomain tolerance, so bare-domain entries such as
five9.comstill require the documentedhttps://.../ *form. That broader behavior is intentionally out of scope here.Expected behavior
https://host/andhttps://hostmatchhttps://host,https://host/, andhttps://host/any/deep/link.https://host.evil.com/must not be matched by an allow entry forhttps://host/.https://google.com/*) and raw regex patterns (^https://login\.microsoftonline\.com$) are unchanged.Notes
The two copies of
urlPatternToRegexincontent.jsandoptions.jsmust stay in sync.