PG1204 opened a new pull request, #7013:
URL: https://github.com/apache/texera/pull/7013

   ### What changes were proposed in this PR?
   
   Closes an SSRF bypass in the HuggingFace inference operator's 
`_fetch_remote_url` (generated Python in `PythonCodegenBase.scala`).
   
   The helper hardens remote fetches (https-only, rejects 
private/loopback/link-local/ reserved addresses incl. the 169.254.169.254 
metadata endpoint, size cap) but validated only the *original* URL, then called 
`requests.get(...)`, which follows redirects by default. Redirects were never 
re-checked, so a 302 to `http://169.254.169.254/...` or an internal host was 
fetched without re-running the scheme/address checks. Every remote fetch in the 
operator routes through this helper, user-provided image/audio URLs and 
provider-returned media URLs, so a malicious input or hostile provider response 
could
   reach internal services and exfiltrate the content via the result column.
   
   The fix follows redirects manually so every hop gets the same scrutiny as 
the original:
   
   - Extracted the scheme + address checks into a `_validate_remote_url` helper 
so it can run per hop.
   - `_fetch_remote_url` sets `allow_redirects=False` and walks the chain in a 
bounded loop (`MAX_REDIRECT_HOPS = 5`), validating before each request; 
relative `Location` values are resolved via `urljoin` and re-validated.
   - Fails closed on a missing `Location` or an over-long chain; intermediate 
responses are closed. Size cap and `raise_for_status` unchanged.
   - Hardened the address check to an allowlist stance: it now also requires a 
globally-routable address (`not ip.is_global`) alongside the existing 
predicates. This additionally blocks the CGNAT/shared range (100.64.0.0/10) the 
predicate list missed and stays correct across Python versions, while keeping 
the explicit predicates (e.g. multicast, which CPython reports as global).
   
   Net effect: a redirect can no longer downgrade the scheme or point the 
worker at a non-public address; legitimate https→https (and relative) redirects 
still work.
   
   ### Any related issues, documentation, discussions?
   
   Closes #6967 
   
   ### How was this PR tested?
   
   Added a generated-code test to HuggingFaceInferenceOpDescSpec pinning the 
fix:
   `allow_redirects=False`, validation running before each request, 
interception of all redirect statuses (301/302/303/307/308), relative-Location 
resolution, the hop cap, the fail-closed errors, and the globally-routable-only 
address check.
   
       sbt "WorkflowOperator/testOnly 
org.apache.texera.amber.operator.huggingFace.*"
   
   Full HF package passes (123 tests), including PythonCodeRawInvalidTextSpec, 
which py_compiles the generated Python of all 117 operators. scalafmt clean.
   
   Beyond the source-level assertions, the redirect logic was manually verified 
by executing the generated operator Python against simulated redirect scenarios 
(no network): http-downgrade, private/RFC1918, 169.254.169.254 metadata, CGNAT, 
multicast, IPv6 loopback/ULA, IPv4-mapped, userinfo-trick, and mixed 
public+private hosts are each blocked and never fetched, while legitimate 
https→https and relative-Location redirects still succeed and the hop cap is 
enforced.
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Co-authored with Claude Fable 5 in compliance with ASF.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to