Skip to content

fix(modules): exempt webdriver transport from SSRF filter 🐛#324

Open
dohernandez wants to merge 1 commit into
v0.3-devfrom
fix/web-render-unfiltered-webdriver
Open

fix(modules): exempt webdriver transport from SSRF filter 🐛#324
dohernandez wants to merge 1 commit into
v0.3-devfrom
fix/web-render-unfiltered-webdriver

Conversation

@dohernandez

Copy link
Copy Markdown
Member

Summary

Field blocker on v0.3.0-rc6 docker deploys: the web module's Render() sends its request to the operator-configured webdriver_host through the SSRF-filtered client. In docker topologies the webdriver hostname resolves to an RFC1918 address, so FilteringResolver drops every resolved address and every docker deploy of the node's boot self-test crash-loops with a non-fatal-but-boot-fatal ADDRESS_FORBIDDEN. Host deploys with webdriver_host: http://127.0.0.1:4444 were unaffected only because IP-literal transport URLs never enter the resolver.

The fix is one line in genvm-web-default.lua: Render()'s webdriver call now passes unfiltered = true, using the opt-out plumbing that Request() already uses for always_allow_hosts. Rationale: webdriver_host is operator-configured infrastructure — the same trust class as the LLM backends, which already go through the plain client (filter_dns=false) — while the contract-controlled input (the render target URL) is validated by web.check_url before the transport request is built. The filtered client remains in place for all contract-controlled fetches.

Also audited per the incident report:

  • LLM/greybox backends: already unfiltered; the web module's Render was the only module-internal transport routed through the filter.
  • Literal-IP bypass for contract URLs (the mirror-image concern): not exploitable. split_url uses the url crate, which normalizes all literal-IP spellings (dotted/decimal/hex) before check_url's TLD check lexically rejects them, and the filtered client's redirect policy rejects IP-literal redirect hops (test_redirect_to_private_ip_is_rejected).

Tests

New modules/implementation/tests/web_render_webdriver.rs, exercising the real genvm-web-default.lua with a filter_dns=true ctx (as the real web module builds it) and webdriver_host on localhost.direct (public DNS resolving only to loopback — the incident topology in miniature):

  • render_reaches_loopback_only_webdriver_host — fails without the fix with the field incident's exact signature (causes: ["ADDRESS_FORBIDDEN"] on the /render URL), passes with it.
  • filtered_default_client_still_blocks_loopback — the same ctx still blocks a plain filtered request to the same host, so the pass above is attributable to the opt-out, not a loosened filter.

Existing SSRF filter tests (request_localhost.rs, 4) pass.

🤖 Generated with Claude Code

In docker topologies the webdriver hostname resolves to an RFC1918
address, so routing Render's request to the operator-configured
webdriver_host through the filtering client crash-looped every docker
deploy with ADDRESS_FORBIDDEN. The contract-controlled target URL is
already validated by check_url; the transport hop now uses the
unfiltered client, like the LLM backends.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f18776d3-a71b-4197-8571-07281e79da3e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/web-render-unfiltered-webdriver

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

GenVM PR actions

Tick a box to run it (the box unticks itself when handled). Actions only run while the PR has the ci-safe label.

  • Force run full tests
  • Rerun full tests
  • Merge into dev

Full GenVM CI runs only when rtm or run-full-tests is set — "Force run full tests" is a sticky toggle for run-full-tests. Adding rtm marks the PR ready-to-merge and also runs full tests. Merge requires: rtm, green full tests, green E2E, and the branch 0 commits behind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants