fix: enable browser SSRF interception by default (H1)
Off-by-default left headless-browser page JS/subresources/redirects able to reach internal IPs (Chromium bypasses the reqwest SafeResolver). The crawler runs in the backend container so it can't be network-isolated without breaking Postgres — the CDP Fetch interceptor is the control. Flip CRAWLER_SSRF_INTERCEPT default to true (config + .env.example + compose); off-path unchanged as break-glass. The #[ignore]'d smoke test validates against real Chromium (command documented). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -520,12 +520,15 @@ pub struct CrawlerConfig {
|
||||
/// exhausted) that trigger an automatic coordinated browser restart.
|
||||
/// Defaults to 3. `CRAWLER_BROWSER_RESTART_THRESHOLD`.
|
||||
pub browser_restart_threshold: u32,
|
||||
/// Opt-in CDP `Fetch` interception that re-validates every headless-browser
|
||||
/// navigation/redirect against the SSRF check (blocks a scraped page that
|
||||
/// redirects the browser to an internal target). Default `false`: enabling
|
||||
/// `Fetch` is a fragile hook in the crawler's critical path and the wiring
|
||||
/// is not CI-verifiable (no Chromium in CI) — validate with a manual crawl
|
||||
/// before turning on. `CRAWLER_SSRF_INTERCEPT`.
|
||||
/// CDP `Fetch` interception that re-validates every headless-browser
|
||||
/// navigation/redirect/subresource against the SSRF check. Default `true`:
|
||||
/// with it off, only the top-level URL string is validated, so a scraped
|
||||
/// page's JS/subresources (which use Chromium's own network stack, not the
|
||||
/// reqwest `SafeResolver`) can reach internal targets like the cloud
|
||||
/// metadata service or postgres. The Fetch hook can't be exercised in CI (no
|
||||
/// Chromium) — the `#[ignore]`d `ssrf_interception_does_not_wedge_allowed_navigation`
|
||||
/// smoke test validates it against a real binary. `CRAWLER_SSRF_INTERCEPT`;
|
||||
/// set `false` only as a break-glass if the hook destabilizes a deployment.
|
||||
pub ssrf_intercept: bool,
|
||||
}
|
||||
|
||||
@@ -559,7 +562,7 @@ impl Default for CrawlerConfig {
|
||||
job_timeout: Duration::from_secs(600),
|
||||
metadata_max_consecutive_failures: 10,
|
||||
browser_restart_threshold: 3,
|
||||
ssrf_intercept: false,
|
||||
ssrf_intercept: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -725,7 +728,7 @@ impl CrawlerConfig {
|
||||
) as u32,
|
||||
browser_restart_threshold: env_u64("CRAWLER_BROWSER_RESTART_THRESHOLD", 3).max(1)
|
||||
as u32,
|
||||
ssrf_intercept: env_bool("CRAWLER_SSRF_INTERCEPT", false),
|
||||
ssrf_intercept: env_bool("CRAWLER_SSRF_INTERCEPT", true),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user