The signing tool keeps no signature on the device (#1, bau-pm BAU-260)
PDF.js's signature dialog saved every signature in localStorage under pdfjs.signature, "save" ticked on every open, for this origin rather than for a bau-pm user. Measured on v0.1.0: a typed and an uploaded signature were offered to a fresh page on the same browser, the way the next person on a shared tablet would get it, a Redmine logout included. Another browser profile saw nothing; the server never had anything. The glue's fifth duty, in every window before PDF.js's modules: delete the store (a device that saved signatures loses them on its first visit), refuse writes to that key, hold the save box unticked through a property on the element and hide it, and hide the dialog's Bild tab and its file picker, so a scanned signature never enters the dialog. test/signatures.mjs is the second gate, in CI and the release workflow: a browser seeded with a real saved entry (captured from v0.1.0's own store) is offered none, the dialog shows neither the box nor the tab, a typed signature is placed and not stored, a fresh page is offered nothing. Fed v0.1.0: 9 findings, exit 1. Against this image: 0, and the zero-host gate drove 117 tool pages with nothing leaving the origin. A signed PDF still exports with the signature on the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ac6d57562b
commit
4248bc791a
8 files changed
+197
-5
No files matched your search
@@ -10,7 +10,8 @@ This repository is public on purpose. BentoPDF is AGPL-3.0, and this is a modifi
|
||||
- **Every module BentoPDF would otherwise load from a CDN**, served from `/wasm/`: PyMuPDF and Ghostscript from BentoPDF's own repository at that commit, CoherentPDF, Tesseract with `deu`, `fra`, `ita` and `eng`, the OCR text-layer font and the PDF editor's Latin, Arabic and Hebrew fallback fonts from npm. `scripts/vendor.sh` packs each one and refuses the build when the registry's integrity differs from `vendor.lock`. The editor's CJK fonts (30 to 42 MB each) are left out; a document that needs them asks this server and gets a 404, never a third party.
|
||||
- **A Content-Security-Policy without a single host**: BentoPDF's generated header file with every `http(s):` source taken out, `img-src` included (`scripts/finish.sh`, which fails the build if any host survives).
|
||||
- **Two tools disabled** in `config/config.json`, because they cannot work without a third party: `digital-sign-pdf` (X.509 signing fetches certificate chains through a CORS proxy) and `timestamp-pdf` (an RFC 3161 timestamp needs an external timestamp authority).
|
||||
- **The glue**, `glue/handoff.js`, added to every HTML page by `scripts/finish.sh`: the source link, the hand-in of a file from bau-pm, the hand-back of a result, and the signing tool's flatten switch locked on. See the file's header for how each works.
|
||||
- **The glue**, `glue/handoff.js`, added to every HTML page by `scripts/finish.sh`: the source link, the hand-in of a file from bau-pm, the hand-back of a result, the signing tool's flatten switch locked on, and no signature kept on the device. See the file's header for how each works.
|
||||
- **No saved signatures, no image signatures.** PDF.js's signature dialog would save up to five signatures in the browser's `localStorage`, with *Unterschrift speichern* ticked by default, for this origin rather than for a bau-pm user: on a shared tablet the next person found the last one's signature one click away, a logout in bau-pm included (issue #1). The glue deletes the store on every page, refuses its writes, holds the box unticked and hides it, and hides the dialog's *Bild* tab, so a scanned signature never enters the tool. Signing means typing or drawing it, each time.
|
||||
|
||||
Nothing of BentoPDF's code is edited: its documented build arguments, its runtime `config.json`, its generated header file with fewer hosts, and our files beside its own.
|
||||
|
||||
@@ -24,6 +25,8 @@ bau-pm runs the image as its `pdf-tools` service on an origin of its own (`PDF_T
|
||||
|
||||
It has teeth: fed the stock upstream image it fails with 115 findings (PyMuPDF, Pyodide and CoherentPDF from jsdelivr), and fed a misspelled disabled id it fails with "no page".
|
||||
|
||||
`test/signatures.mjs` is the second gate, run in the same step: on a browser that already holds a saved signature (a real entry, `test/fixtures/saved-signature.json`) the signing tool offers none and the store ends up empty; in its dialog the save box and the image tab are hidden; a typed signature, once placed, is not stored; and a fresh page, the next person, is offered nothing. Fed v0.1.0 it fails with 9 findings.
|
||||
|
||||
Locally (bridged containers need no internet for it):
|
||||
|
||||
```sh
|
||||
@@ -32,6 +35,7 @@ docker build -f test/Dockerfile -t bau-pm-pdf-tools-gate:ci .
|
||||
docker network create pdf-gate
|
||||
docker run -d --name pdf-gate-app --network pdf-gate --network-alias pdf-tools bau-pm-pdf-tools:ci
|
||||
docker run --rm --network pdf-gate bau-pm-pdf-tools-gate:ci node test/zero-hosts.mjs http://pdf-tools:8080
|
||||
docker run --rm --network pdf-gate bau-pm-pdf-tools-gate:ci node test/signatures.mjs http://pdf-tools:8080
|
||||
docker rm -f -v pdf-gate-app && docker network rm pdf-gate
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user