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 convert.cantopenpdf.com, 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://convert.cantopenpdf.com/ | 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 convert.cantopenpdf.com 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 [email protected], 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 09d94111cf6f, built 2026-11-04T13:48:10.043Z. Fonts, character maps and colour profiles are listed in SHA256SUMS.txt.

FileSHA-256
_headers16e056bcd8fe126b6c856a3300c9031e84e535855072130af8c2d51689b6b2cf
app.jsaf229b45184c1f679f20247063fbfb48aba637b14aa096b293fe0e018acc4ba4
config.jsb3250cb7d51b7fadd5d6f2bacadb375a07f76e61e6ea778dbaa8d83d74a71770
convert.css11b82b902229cbeb66495349d008f99eac9b71ab41824d8993865889392d3820
detect.js315a409272357faf4afffbf0890435c24c47c0cbe3414ad099b8efdda6185143
favicon.svgac6e9d6a2c011a002d43f9c59620f18183ee92c7501c97bae7fcf2ef998f6729
index.htmlb67f00d00308e7e2439f0f35ec89e6d6ea5e5f279485bc0a8b00f7140ac9c090
js-normalize.js9cf981fb884065013123694622e7adb3e46f724200c2af3f45ed15d1555c88aa
pdf-xfa-worker.js2e4e0b9f4165c05b941825d933ac4dc11312270e389b8cf6247b53bf7d2c63ae
pdf-xfa.js793d980da24f567765ab3b4714b85a1e47a2e325d4e08b8cb047e504feae1d9f
pdf417-tables.js04e6be0b0ffebe03ee52615c7a4cd7be7e5e00601de4b17049a7a3e1a63da8b1
pdf417.js67aa53d01ec3c74307d366b2c5886ef0731cb5ae21119b74b0b52cf446e72cfa
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.json7de1a061c25d1bc897a4ec33431f017abddad168ef24c23f6a30daecbd067413
robots.txt331ea9090db0c9f6f597bd9840fd5b171830f6e0b3ba1cb24dfa91f0c95aedc1
shared/catalog.js8f625849ea6c41cd7f853649dadd4474a860cd5de2b12fec37734ea067b3e890
xfa-fixups.jsd463b7aa929df05cbdc6f740f93cbfbb91ea2dff0913be3eca4f9cbf92e60937
xfa-prepare.jsdf89982bfb94617901cd6191d4ad39223f8f3257f4f99b1ada60546a0abf0789
xfa-scripts.jsd61783e78f502bc0fe29c2050b5abf186c037685568033635560128178c87248
xfa.cssc343704d5d804a2ccc57e65cf323ded52c0b1bcd8523089f468be964ce1c7c19

Report a problem

Found a security issue? Email [email protected]. See also security.txt.