Files
safetynet/docs/windows-file-uploads.md

4.0 KiB

Windows file upload enforcement

Ordinary file-backed uploads now use the original Chromium request with protected Windows handles. The browser scans the complete actual files and the ordered multipart byte segments before releasing the request. File magic, central DLP, enabled local semantic/YARA checks and configured upload ICAP inspection apply. This preserves Chromium's credential, cookie and CORS handling; requests are not forwarded through a second fetch operation.

Eligible paths are canonical absolute local NTFS paths, at most 240 characters, without alternate streams, device paths or reparse points. The gate supports full file descriptors with offset zero and length minus one. It bounds the complete request by the signed DLP byte limit, supports at most 16 file descriptors per lease and eight outstanding leased requests. Partial file ranges, UNC paths, data pipes, blobs without file descriptors, streams and changed-destination upload redirects remain blocked pending their own safe integrations.

The private helper opens each normal ancestor and the file with read-only sharing, verifies handle-derived path, volume and file identity, and reads through that same handle. Writable mappings and incompatible handles cause refusal. Each lock is also duplicated into the browser main process before acknowledging acquisition. Killing the helper therefore does not remove the browser-owned locks.

Handles stay held until the matching native completion/error event. Policy changes, scanner denial, timeouts, redirect or helper failure alone never release them. A confirmed terminal event permits explicit cleanup, including a trusted replacement helper after helper death. Remote handle closure is one-shot: an uncertain close is never retried because Windows may recycle a handle value. Unexpected helper/protocol failure disables acquisition and keeps the browser in quarantine across policy refresh until restart. Unknown handle receipts remain locked until the owning browser process exits.

Snapshot buffers are cleared after inspection. File content is not persisted by this gate. Ordinary transfer audit retains hash-free total request bytes and type, decisions, policy version and trace correlation; it does not fingerprint an entire multipart credential envelope. JavaScript/base64 string copies cannot be reliably overwritten and are garbage-collected.

Actual verification

  • Real Windows tests reject writes, hardlink writes, renames, junctions, excessive sizes, pre-existing write handles and writable mappings.
  • Actual managed Electron uploads deliver exact allowed file bytes once and keep a confidential file from reaching the receiver.
  • Actual redirect/helper-death tests confirm denied redirect targets, terminal cleanup, and persistent fatal quarantine.
  • Package verification exercises the shipped helper and Python runtime, including blocked overwrite/rename followed by explicit cleanup.

Evidence: artifacts/native-file-upload-proof.json, artifacts/upload-lifecycle-native-proof.json, tests/upload-lease.test.mjs and tests/file-upload-gate.test.mjs.

These checks concern the tested ordinary NTFS file path. They do not establish every filesystem/filter-driver behavior, browser-main crash behavior while a network service survives, protection against privileged OS manipulation, or all remaining streaming/native Chromium enforcement requirements.

Debug observability

browser.upload.lease, browser.upload.part, browser.upload.release and browser.upload.fault provide phase timings. Local worker stages are children of the relevant inspection span. Fixed safetynet.reason values identify context changes, deadlines, invalid ownership and lost/failed handle leases. Arbitrary rule strings and exception contents cannot become reason attributes.

A real helper termination exported upload-lease-lost in a fault span and two correlated logs, linked to its original lease parent and the durable audit event: trace e6d26d4edf738a7b4f6f562ab2112f5b (fault stage 36.27 ms). Proof: artifacts/native-upload-fault-trace-proof.json.