51 lines
2.7 KiB
Markdown
51 lines
2.7 KiB
Markdown
# 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-sandbox` flag where possible
|
|
- Add tests verifying that blocked URLs are not accessible
|
|
|
|
steps:
|
|
1. Examine `generatePDF()` at `web/src/server/services/reports/generator.ts:141-150` and `compileData()` at lines 53-137
|
|
2. Add `page.setRequestInterception(true)` before `page.setContent()` to intercept all network requests
|
|
3. 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
|
|
4. If `--no-sandbox` is required by the deployment environment (e.g., Docker), document the risk and add a compensating control (Chrome flags, network namespace isolation)
|
|
5. 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/passwd` does 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-sandbox` flag is either removed or has documented compensating controls
|
|
|
|
validation:
|
|
- `cd web && bun test` — all tests pass
|
|
- Attempt to inject a `file:///etc/passwd` URL through report data and verify it is blocked
|
|
- Verify report generation still produces valid PDFs
|
|
|
|
notes:
|
|
- Finding p8-002: The `--no-sandbox` flag 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/...">`
|