fix(#6844): support wildcard hostnames in SSRF hook egress allowlist - #6845
fix(#6844): support wildcard hostnames in SSRF hook egress allowlist#6845fullsend-ai-coder[bot] wants to merge 2 commits into
Conversation
The SSRF pre-tool hook silently dropped wildcard entries (e.g. *.atlassian.net:443) from FULLSEND_EGRESS_ALLOWLIST with a warning, causing DNS-failure fail-closed blocks for hosts that the network policy intended to allow. This broke Jira integration for orgs using wildcard policies like *.atlassian.net. Add leading-wildcard suffix matching to _parse_egress_allowlist() and _is_host_allowlisted(). Only the *.domain form is accepted — bare * and mid-string globs remain rejected. Matching requires at least one subdomain label (*.example.com matches sub.example.com but not example.com itself) and uses domain-anchored suffix comparison to prevent spoofing (atlassian.net.evil.com does not match *.atlassian.net). Closes #6844
|
🤖 Finished Review · ✅ Success · Started 12:16 PM UTC · Completed 12:35 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $6.97 |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Risk Assessment: moderate (2/5) DetailsModerate risk preserved from prior assessment. Tier 1 remains low (small 3-file change, 0.33 test ratio, bot-authored, no protected paths); Tier 2 still elevated due to high churn (13 commits/30d), multi-author contention (5 authors/90d), and heavy regression activity (14 fix/revert commits/90d) on ssrf_pretool.py; Tier 3 adds caution from security-labeled issue modifying SSRF allowlist parsing. Previous runRisk Assessment: moderate (2/5) DetailsModerate risk. Tier 1 is low (small 2-file change, 0.50 test ratio, bot-authored, no protected paths), but Tier 2 elevates due to high churn (13 commits/30d), multi-author contention (5 authors/90d), and heavy recent regression activity (14 fix/revert commits/90d) on ssrf_pretool.py. Tier 3 adds caution from security-labeled issue and the fact that modifying SSRF allowlist parsing changes runtime security behavior. |
ReviewFindingsLow
Next steps:
Previous runReviewFindingsMedium
Low
Labels: PR modifies SSRF security hook in internal/security/hooks/ Next steps:
|
|
🤖 Finished Fix · ✅ Success · Started 12:37 PM UTC · Completed 12:43 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $1.69 |
Move rstrip(".") before the wildcard-shape check in _parse_egress_allowlist
so entries like "*..:443" are correctly rejected instead of silently collapsing
to ("*", 443). Update FULLSEND_EGRESS_ALLOWLIST docs in runtime-implementation
to reflect leading-wildcard support.
Addresses #6845
🔧 Fix agent — iteration 1 (bot-triggered)Addressed both review findings: (1) updated FULLSEND_EGRESS_ALLOWLIST documentation to reflect leading-wildcard support, (2) fixed edge case where trailing-dot wildcards like ..:443 silently collapsed to ('', 443) by moving rstrip(".") before validation. Added regression test for the edge case. All 157 tests pass. Fixed (2):
Tests: passedNext steps:
|
|
🤖 Finished Review · ✅ Success · Started 12:45 PM UTC · Completed 1:05 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $6.15 |
| else: | ||
| wc_host = entry | ||
| wc_port = 0 | ||
| wc_host_clean = wc_host.lower().rstrip(".") |
There was a problem hiding this comment.
[low] authorization/allowlist-scope
The wildcard parser accepts broad TLD-level patterns like *.com:443 or *.net:443, which would allowlist egress to every subdomain under that TLD during DNS failures. While FULLSEND_EGRESS_ALLOWLIST is operator-controlled infrastructure (not user-facing), there is no minimum label-depth validation to prevent accidentally over-broad entries. A misconfigured *.com entry would effectively disable SSRF fail-closed behavior for the entire .com namespace.
Suggested fix: Consider requiring at least two labels after the wildcard (e.g., reject *.com but accept *.example.com) by checking wc_host_clean.count('.') >= 2 before accepting the entry, or by emitting a loud warning for single-dot patterns.
Summary
Adds wildcard hostname support to the SSRF pre-tool hook's egress allowlist, aligning it with the network policy layer that already supports wildcards. Previously, wildcard entries like
*.atlassian.net:443inFULLSEND_EGRESS_ALLOWLISTwere silently dropped, causing DNS-failure fail-closed blocks for Jira integration users whose sandbox policies use wildcards.Changes
internal/security/hooks/ssrf_pretool.py:_parse_egress_allowlist(): Accept leading*.domainwildcard entries (stored as("*.domain", port)tuples). Bare*and mid-string globs remain rejected with a warning._is_host_allowlisted(): After exact matching, iterate wildcard entries and perform domain-anchored suffix matching —*.atlassian.netmatchesredhat.atlassian.netbut notatlassian.netitself (requires at least one subdomain label) and notatlassian.net.evil.com(suffix-spoof prevention).internal/security/hooks/ssrf_pretool_test.py:test_wildcard_entries_ignored→test_leading_wildcard_entries_acceptedTestWildcardAllowlistMatchingclass (10 tests): subdomain match, multi-level subdomain, base domain rejection, suffix-spoof rejection, port matching, case insensitivity, trailing dot handlingvalidate_urlintegration tests: wildcard allows subdomain on DNS failure, blocks base domain, blocks wrong portTesting
ruff checkandruff formatpassCloses #6844
Post-script verification
agent/6844-ssrf-wildcard-allowlist)6439d79a40fa67505cdc916384b2a278a31a1942..HEAD)