Security & how to verify it

Your PDF is processed locally, in your browser. Our converter code does not upload it. A separate website and a restrictive security policy limit what the converter can do on the network. This page explains exactly what that means, what it doesn't mean, and how to check it yourself.

1. The airplane-mode test (anyone can do this)

  1. Open any page on this site and wait for it to load.
  2. Turn on airplane mode, or disconnect from Wi-Fi.
  3. Drop your PDF into the box. It opens anyway.

This shows the conversion itself doesn't need a server. It's a quick check, not a proof. The technical checks below go further.

2. How it's built

  • A separate website for the converter. The converter runs on cantopenpdf-convert.pages.dev, isolated from this site by your browser's same-origin rules. Scripts on this site, including our analytics, can't read your file. That host serves static files only and has no server code.
  • No third-party hosted or tracking scripts. No ad networks, no Google Analytics, no CDNs. Every script is served from our own domains. The PDF engine, Mozilla's pdf.js 6.4.299, is third-party open-source code that we host ourselves, unmodified and pinned to an exact version.
  • Read-only pages. Embedded PDF scripts never run, document links aren't followed, and form fields and buttons are disabled.
  • No cookies or device storage. Neither site sets cookies or uses local storage, session storage or IndexedDB.

3. What the security policy does, and doesn't do

The converter's Content-Security-Policy includes default-src 'none', connect-src 'self', form-action 'none' and frame-src 'none'. Your browser enforces it. It:

  • blocks the page from making network connections (fetch, XHR, WebSocket) to any host other than the converter's own static host
  • blocks form submissions and loading scripts, frames or plugins from anywhere else

It doesn't, on its own, prove that no data could ever leave your device:

  • Requests to the converter's own host are still allowed, for example to load fonts.
  • It doesn't govern messages the converter sends to this site (see section 4) or links you choose to follow.
  • It can't protect against browser extensions or malware already on your device.

Our guarantee is that our code doesn't send your document anywhere. The policy is an extra layer that limits the damage if something went wrong.

4. Exactly what the converter tells this site

The converter sends this page short messages so we can show relevant help and count what works. Each message can contain only:

  • an event name (file opened, displayed, failed, incomplete, password needed, print requested)
  • a document type from a fixed list built into the code, for example sars:audit, ircc:imm5257, unknown
  • the number of pages, a size range (such as “0.5–2 MB”), and whether the file was an XFA form

The converter never sends text, names, numbers, reference codes or field values from your document, and anything outside the fixed list is reported only as unknown. This site checks every message against the same list before recording it. See post() in app.js and the list in catalog.js.

This site records those events, plus the page you're on and how you arrived (campaign tags, referring site, country and device type), with a random visit ID that lives only in the page and in the link to our help form. It isn't stored on your device and isn't reused on later visits. Details are in the privacy notice.

5. Check it yourself (technical)

  • See the policy: curl -sI https://cantopenpdf-convert.pages.dev/ | grep -i content-security-policy
  • Open your browser's developer tools, go to the Network tab, and convert a file. The only requests go to cantopenpdf-convert.pages.dev for the app's own static files.
  • Our code isn't minified. Read app.js, detect.js and catalog.js directly.
  • Compare pdf.js with the official package: npm pack pdfjs-dist@6.4.299, then shasum -a 256 package/build/pdf.min.mjs (served here as pdfjs-6.4.299/pdf.min.mjs).

The hashes below are published by the same server they describe, so they're useful for comparing files, not independent proof of where the files came from. Our CI checks selected invariants on every change: the security policy directives, a list of files allowed in a release, byte-identical pdf.js, and a browser test that a document's text never appears in any network request or message.

Converter file hashes (SHA-256)

Release f14effe78ce5, built 2026-11-04T08:21:56.575Z. Fonts, character maps and colour profiles are listed in SHA256SUMS.txt.

FileSHA-256
_headers0ac19b91809b77a465b6a7ec363bcbc2b630c65ec35ce181c1ec584570f91d10
app.js0cc065cc03c260ffc25acb0f3ca5c9bc41ce53421afe1b7a231dabbc0ab71b75
config.js3b3415ecc501341f8d2036fc1a2c85998619a3a13e989ee206ee1e4799cfc2a9
convert.css3cabf5ee37019a3393458c497d392c5fd88439ab36c7b2b2042e437ed2727acb
detect.js315a409272357faf4afffbf0890435c24c47c0cbe3414ad099b8efdda6185143
favicon.svgac6e9d6a2c011a002d43f9c59620f18183ee92c7501c97bae7fcf2ef998f6729
index.htmlcf753af807296bcc57b598a0e1a9585772f257e92879f7767b3bf89b924db680
pdfjs-6.4.299/LICENSE0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594
pdfjs-6.4.299/pdf.min.mjs57456c8e0c81e46be31174b499ef77f2b9f5ee46d04412ba627320a36755d4c2
pdfjs-6.4.299/pdf.worker.min.mjs9536359f1b8367850d485731ca1d5e45c159a7b7a0912325e539937aa21ceb18
pdfjs-6.4.299/wasm/LICENSE_JBIG29e66b7f1b934a28b37f3bc4dac97915de1674271e79a0a88182a18ed9731b4d1
pdfjs-6.4.299/wasm/LICENSE_OPENJPEGa6af136f3e15038a666b61f376612a07d9a4e48cb7c01adbf3e33b3f14ab49b6
pdfjs-6.4.299/wasm/LICENSE_PDFJS_JBIG2aad3cce09842e00e9e11ad5e8fef8cc02fbc3a3768fe2f007443b9cee37aaee5
pdfjs-6.4.299/wasm/LICENSE_PDFJS_OPENJPEG717fc62da03292dbb4dd0c8280bd4ce7bb8550dcf31d772bc93455fb50313425
pdfjs-6.4.299/wasm/LICENSE_PDFJS_QCMS508a77d2e7b51d98adeed32648ad124b7b30241a8e70b2e72c99f92d8e5874d1
pdfjs-6.4.299/wasm/LICENSE_QCMS36d847ae882f6574ebc72f56a4f354e4f104fde4a584373496482e97d52d31bc
pdfjs-6.4.299/wasm/jbig2_nowasm_fallback.js68686ced624a48c42f84cdaa482ec44b72b0de4dc84a0df903af1fb7b45b5d9a
pdfjs-6.4.299/wasm/openjpeg_nowasm_fallback.js9047b34b6bc142d85e4b0aa1b08b0b9baad4c6f8b7ac87641b9e8f90eb6fd23e
release.json823dd3762f0130bd492a3be5349d5276bbaef8ac710d24f98602d048514d0d58
robots.txt331ea9090db0c9f6f597bd9840fd5b171830f6e0b3ba1cb24dfa91f0c95aedc1
shared/catalog.jsc71e97eb64e5532c39fa7e6715c4df222761fdeb67f0d9c81e882592a9bf55de
xfa.cssc343704d5d804a2ccc57e65cf323ded52c0b1bcd8523089f468be964ce1c7c19

Report a problem

Found a security issue? Email security@cantopenpdf.com. See also security.txt.