T05 · Unauthorized Access and Privilege Escalation
- Location
pw-browser.js:672- Finding
Safe Mode Permits Arbitrary Local-File Disclosure Through Browser Uploads
- Content
View full analysis
s.trim()).filter(Boolean) : []); await el.setInputFiles(files); return { ok: true, ref, uploaded: files }; } ``` The directly exposed HTTP command contains the same behavior: ```js case 'upload': { const r = await resolveRef(p, params.ref); if (r.error) return json({ ok: false, error: r.error }); const files = (params.files || '').split(',').map(s => s.trim()).filter(Boolean); await r.el.setInputFiles(files); json({ ok: true, ref: params.ref, uploaded: files, elapsedMs: Date.now() - t0 }); break; } ``` Safe mode is optional and does not affect either upload implementation: ```js const SAFE_MODE = process.env.PW_BROWSER_SAFE_MODE === '1' || process.env.PW_BROWSER_SAFE_MODE === 'true'; ``` ### Technical Analysis The upload commands pass caller-selected local paths directly to Playwright's `setInputFiles`. This causes the browser process to read the selected files from the host filesystem and expose their contents to the current website's file input. Neither upload path applies: - A safe-mode prohibition - A permitted-directory allowlist - Canonical-path or symlink validation - File-type or file-size restrictions - Per-upload user confirmation - A distinction between ordinary browser interaction and host-file access The daemon bearer token controls access to the complete API, but it is not a capability-specific authorization boundary. Consequently, an agent that is intentionally placed in safe mode still retains a host-file read and network-transfer primitive. This exceeds the minimum privileges require ...[truncated 1144 chars]- Remediation
View remediation
