75 lines
6.4 KiB
Markdown
75 lines
6.4 KiB
Markdown
# 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.
|
|
|
|
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.
|