Fix SSRF guard rejecting private proxies - #2762
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
This PR adds proxy handling to the SSRF-guarded HTTP/HTTPS connection machinery in graphify/security.py. It introduces two new connection subclasses (_ProxyAwareHTTPConnection and _ProxyAwareHTTPSConnection) that skip the SSRF IP validation on the connect step, and updates the HTTP/HTTPS handlers to route requests through these proxy-aware classes when a proxy or tunnel host is detected on the request. The surface area is limited to the connection/handler classes governing outbound request routing.
Worth a look
- HTTPS proxy CONNECT tunnel target not SSRF-validated —
graphify/security.py:234· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review Execution auto-disposal is off for this run; enable it (with sandbox isolation) to have Graphify try to confirm or refute this automatically.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1130 functions depend on the 47 functions this change touches.
Health — grade A; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):
_rebuild_code()— 95 callers, 51 callees (high)build_merge()— 41 callers, 14 callees (high)_extract_generic()— 18 callers, 23 callees (high)extract_bash()— 40 callers, 10 callees (high)extract_xaml()— 19 callers, 17 callees (high)ingest_scip_json()— 76 callers, 4 callees (high)to_json()— 44 callers, 6 callees (high)dispatch_command()— 2 callers, 117 callees (high)- …and 2 more
Verification — 1130 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 420 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify http\_open.
The verifier did not have enough to check http\_open, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify https\_open.
The verifier did not have enough to check https\_open, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
|
user@rhovanion graphify % git checkout fix-issue-2761 user@rhovanion graphify % cd ~/tmp ; graphify add https://www.bbc.co.uk Looks like the proposed fix gets further than before, but it bumps into an SSL cert error. My proxy is running squid and functions fine for normal web browsing: user@rhovanion Programming % curl -vI https://www.bbc.co.uk
< HTTP/1.1 200 Connection established (private domain names removed for privacy). |
Fixes #2761
This PR modifies the SSRF guard connection classes (
_SSRFGuardedHTTPConnectionand_SSRFGuardedHTTPSConnection) to be proxy-aware. When a request is explicitly configured to use a proxy, the private IP address check is bypassed for the proxy endpoint itself, whilevalidate_urlindependently preserves SSRF protections for the final destination URL.Changes:
_ProxyAwareHTTPConnectionand_ProxyAwareHTTPSConnectionsubclasses to safely connect to proxies without applying IP blocking on the proxy's resolved address._SSRFGuardedHTTPHandlerand_SSRFGuardedHTTPSHandlerto detect if the request is using a proxy (req.has_proxy()orreq._tunnel_host) and dispatch to the correct connection type.