2.7 KiB
2.7 KiB
02. Fix SSRF via Puppeteer --no-sandbox in report generation
meta: id: security-fixes-02 feature: security-fixes priority: P1 depends_on: [] tags: [implementation, tests-required, medium-severity]
objective:
- Prevent SSRF and local file read in the PDF report generator by sandboxing Puppeteer network access
deliverables:
- Add request interception in Puppeteer to block dangerous URL schemes (file://, metadata endpoints, internal IPs)
- Remove or mitigate the
--no-sandboxflag where possible - Add tests verifying that blocked URLs are not accessible
steps:
- Examine
generatePDF()atweb/src/server/services/reports/generator.ts:141-150andcompileData()at lines 53-137 - Add
page.setRequestInterception(true)beforepage.setContent()to intercept all network requests - Implement a request filter that blocks:
file://scheme (local file read)- Cloud metadata endpoints (
169.254.169.254,metadata.google.internal, etc.) - Internal IP ranges (
10.x.x.x,172.16-31.x.x,192.168.x.x,127.x.x.x) data:URIs that could load arbitrary content
- If
--no-sandboxis required by the deployment environment (e.g., Docker), document the risk and add a compensating control (Chrome flags, network namespace isolation) - Add unit tests for the request interception filter
tests:
- Unit: Request interception blocks
file://,data:, internal IPs, and cloud metadata endpoints - Unit: Request interception allows legitimate external URLs (CDN assets, fonts, etc.)
- Integration: Attempting to load a report with embedded
file:///etc/passwddoes not succeed - Integration: Report generation still produces valid PDFs for legitimate content
acceptance_criteria:
- Puppeteer page cannot make network requests to blocked URL schemes or internal IPs
file://URLs are blocked, preventing local file read- Cloud metadata endpoints are blocked
- Report PDFs still render correctly for legitimate content
- The
--no-sandboxflag is either removed or has documented compensating controls
validation:
cd web && bun test— all tests pass- Attempt to inject a
file:///etc/passwdURL through report data and verify it is blocked - Verify report generation still produces valid PDFs
notes:
- Finding p8-002: The
--no-sandboxflag is likely required in containerized environments; if so, network-level sandboxing via request interception is the compensating control - Consider using
page.setContent(html, {waitUntil: 'networkidle0'})with interception enabled - The
compileData()function builds HTML from database data — any user-controlled data in reports could include<img src="file://...">or<link href="http://169.254.169.254/...">