Files
safetynet/docs/immutable-upload-feasibility.md
T

74 lines
6.4 KiB
Markdown
Raw Normal View History

2026-10-13 10:33:31 +02:00
# Immutable native upload binding: Electron 44.7 feasibility
The protocol-forwarding proof below is **not a production upload implementation**
and its credential widening remains a blocker. A separate native-handle path is
now implemented for ordinary Windows NTFS files; see
[Windows file upload enforcement](windows-file-uploads.md). Unsupported data-pipe,
range and streaming paths remain blocked. The earlier candidate/prototype sections
below describe the experiments that preceded that implementation.
2026-10-13 10:33:31 +02:00
Run `node scripts/immutable-upload-probe.cjs`. It launches a finite, hidden, CPU-rendered, sandboxed Electron fixture against a loopback HTTP receiver. No managed browser configuration, actual credentials, OS clipboard, or website code is changed. The fixture uses a real HTML file input populated through test-only native CDP, then submits Chromium-generated multipart FormData.
## Evidence
`artifacts/immutable-upload-probe.json` records:
- `requestBodyAvailable: true`: `session.protocol.handle('http')` exposes the real multipart file stream through `Request.arrayBuffer()`.
- `mutatedAfterSnapshot: true`: the disk fixture is replaced after body capture and before forwarding.
- `exactBytes: true`: receiver SHA-256 equals inspected snapshot SHA-256; receiver contains the original bytes and excludes the replacement bytes.
- `credentialsPreserved: false`: both renderer `credentials: 'include'` and `credentials: 'omit'` become protocol requests reporting `credentials: 'same-origin'`, with no Cookie header. Forwarding through the same session attaches its synthetic session cookie to both. The original credential choice cannot be inferred from these fields.
- `redirectDenied: true`: forwarding with `redirect: 'error'` denies a 307 and never reaches the redirect destination. Transparent redirect compatibility is therefore not established.
The cookie behavior is a security blocker for a transparent HTTP(S) protocol bridge. The proof deliberately asserts this limitation rather than presenting a passing byte comparison as sufficient approval to ship.
## Compatibility and security boundaries
Electron documents that protocol requests include a trusted `initiatorOrigin`. This establishes the requesting origin; it does not recover the original Fetch credential mode, top-level site cookie context, authenticated request semantics, redirect chain, or full request policy context.
CORS preservation has **not been demonstrated**. Browser preflight handling, credential-dependent `Access-Control-Allow-Origin` rules, opaque responses, response URL/type, frame/site cookie partitioning, authentication challenges, and service-worker paths require separate receiver-based tests and implementation support. They must not be inferred from same-origin multipart success. Electron explicitly documents incorrect response `.type` and `.url` for `session.fetch`, and says bypassing custom protocols still invokes `webRequest` handlers. Consequently an integration also needs safe request identity and recursion handling; a broad trusted forwarding bypass would weaken existing enforcement.
The anonymous-only fallback was not implemented. A deployable solution must preserve original Chromium request semantics and bind the scanner decision to immutable bytes, destination, policy version, identity, and request context. Native Chromium interception or a verified native network integration remains required before file/data-pipe upload support can be enabled.
## Primary references
- [Electron protocol.handle documentation](https://www.electronjs.org/docs/latest/api/protocol#protocolhandlescheme-handler): protocol request body and trusted initiator origin.
- [Electron session.fetch documentation](https://www.electronjs.org/docs/latest/api/session#sesfetchinput-init): Chromium network stack, response limitations, custom-protocol bypass and continuing webRequest callbacks.
This test concerns one in-memory multipart upload. It does not prove full DLP coverage for streaming, WebSockets, WebRTC, browser uploads, or downloads.
## Windows file-handle alternative: actual native proof, 2026-10-13
A separate sandboxed Electron 44.7.0 fixture now demonstrates a viable path for
ordinary file-backed multipart uploads without forwarding or rewriting requests.
It holds restrictive Win32 handles for all eight normal ancestor directories and
the leaf file, reads the candidate scan bytes through that same held file handle,
then lets the original Chromium request continue. The real receiver saw original
file bytes; attempted overwrite, hardlink overwrite, leaf rename and parent rename
were refused. Chromium's reader could coexist with the handles. Fetch
`credentials: omit` remained anonymous and `include` retained its cookie. Both
handle sets were released only after their corresponding native `onCompleted`
events. Proof: `artifacts/upload-lock-native-proof.json`; reproducible ignored
fixture: `artifacts/upload-lock-native.cjs` and `upload-lock-helper.py`.
Separate Windows experiments verified that a pre-existing writable mapping causes
restrictive lock acquisition to fail. A lock failure must block; the mapping can
still mutate the underlying file. These observations use synthetic files on this
Windows machine and are not a general filesystem or privileged-attacker guarantee.
This is **not enabled in the product**. The fixture knows its synthetic paths and
does not implement production reparse rejection or identity verification. The
next gate must restrict eligibility to supported local fixed-volume files, retain
the complete normal ancestor chain, verify final path/volume/file identity, and
bound whole-file reads through the held handle. Whole-file inspection avoids
trusting the exposed offset/length conversion for large ranges. It must inspect
both each actual file and the other multipart segments, preserve request order,
and keep handles until the matching native terminal event. Helper death, policy
changes, cancellation, redirects, retries and uncertain lifecycle state require
explicit safe handling before release of either handles or requests. Data pipes,
streaming and other operating systems remain separate requirements.
The existing public-API forwarding bridge remains unsuitable because of its
credential widening. This proof advances ordinary Windows file binding through
native operating-system handles while preserving the original network request.
See [Microsoft CreateFileW](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew)
for the underlying access and sharing contract.