Skip to content
NEXPAPER

Security

Papers that are nobody else's business, and honest words about them

A filing cabinet for the household holds tax assessments, contracts and medical bills. So the advice for nexpaper is a plain one: keep it in your own network, and reach it on the road through a VPN. If you put it on the internet anyway, you find a second factor, passkeys and a self-check waiting for you from the start. Here is what that protects, and just as plainly, where it stops.

What is not on the internet at all is safest

nexpaper is built for your own network. Whoever wants their papers on the road goes into the home network with a VPN (WireGuard, Tailscale, NetBird and the like) and opens nexpaper from there. That is safer than opening a port, and it is enough for nearly everything you need away from home: photographing the tradesman's bill, finding the contract for the dealer.

Some people want to reach nexpaper from outside anyway, and it is prepared for that. It asks every account for a second factor, slows down the guessing of passwords and checks itself. The steps are in the guide chapter Running it. This page is about what lies behind them.

Signing in with a second factor, required from the start

A guessed or stolen password should not be enough to read a person's papers. So out of the box nexpaper asks every account that signs in with a password for a second factor.

Password and code

A password has at least 12 characters and is stored with Argon2id. Right after the password every account sets up a code from an authenticator app, and only then does it go on. Then nexpaper shows eight recovery codes once, which belong on paper, apart from the phone. Each one gets you in once when the phone is gone.

Passkeys

With a passkey you sign in with a fingerprint, your face or the PIN of the device, without a password and without a code. A passkey counts as two factors by itself and cannot be phished. You add up to ten per account under “My account”, “Security”. Passkeys need https under the public address, or localhost.

The operator can switch the requirement off under “Settings”, “Sign-in” with “Require a second factor”. “Ready for the internet?” then reports it as open. If a phone is lost you still get back in: the operator can remove the second factor of an account, the person sets it up again at the next sign-in and is told about it.

My account
My account, tab “Security” with the cards Password, Second factor, Passkeys and Signed-in devices.
Second factor, passkeys and devices in one place.

With the tick “Stay signed in on this device” a sign-in ends after 30 days without use. Without the tick it ends after 12 hours. The operator sets the number of days with NEXPAPER_SESSION_DAYS. The cookies cannot be read by scripts.

You can see where you are signed in

Signed-in devices

Under “My account”, “Security” you find every device your account is signed in on, with its network and last use. Each can be signed out on its own, and “Sign out everywhere else” ends all the others at once. Changing your password signs out all other devices too.

A notice about a new sign-in

When your account signs in on a device nexpaper does not know yet, you are told, by push to your devices and by mail if a mail server is set up. It says which device, which browser and roughly from where. If it was not you, one tap signs that device out. The switch “Tell me about a new sign-in” is on out of the box.

Guessing does not pay

After five wrong sign-in attempts the account waits 15 minutes, and so does the address the attempts came from. Every attempt is in the log. This cannot be set, it is always on. Wrong keys from devices and programs count like wrong passwords.

  • Behind a proxy nexpaper has to see the visitors' real addresses, or it takes everybody for one. How that works is further down.
  • A link to reset a password works once and for 24 hours. Nobody sets a password for another person, the operator included.

Signing in through your own provider

If you already run a sign-in service, authentik for example, you enter it under “Settings”, “Sign-in”. nexpaper speaks OpenID Connect with the authorization code flow and PKCE, and knows one provider. The sign-in page then shows a button “Sign in with …”, and new people only get an account if the operator switches on “New people get an account”. Signing in with a password can be switched off for members; the operator can always use theirs.

For authentik there is a button: with an API token that may create applications, nexpaper sets up the provider and the application itself. The token is used for that only and is not stored. If you would rather do it by hand, download a blueprint instead.

Good to knowEven those who come in through the provider set up nexpaper's own second factor out of the box. Only when the operator switches on “… checks the second factor” does nexpaper not ask again at that sign-in. That is only safe if the provider itself asks for one.

nexpaper checks for itself whether it is ready for the internet

Under “Settings”, “Sign-in” the card “Ready for the internet?” stands at the top. It checks eight points anew each time the operator opens the page, marks each one “fine”, “check” or “open” and says what to do.

PointWhat nexpaper checks
Public address with httpswhether the public address begins with https. Without https, passwords travel the network in the clear, and Web Push and passkeys do not work at all.
Second factor for everybodywhether every account with a password needs a code or a passkey
Your own accountwhether the operator's account, which may change everything, has a second factor itself
Protection against guessingwhether the brake holds and no public networks are listed as proxies
Sessions and cookieswhether the sign-in cookies go only over https and cannot be read by scripts
Behind the proxywhether the visitors' real address arrives or an unknown proxy sits in between
Server secretswhether the key for the mail password, the AI key and the like can be read by its owner only
Backupwhether an automatic backup is on. The documents belong in your server's own backup.

The card checks what nexpaper can know about itself. It cannot see whether your router, your proxy and your server are up to date. The operator can also keep the settings in the home network entirely: with NEXPAPER_OPERATOR_NETWORKS, say 192.168.0.0/16, nexpaper refuses every change of the settings from anywhere else.

The documents lie readable on the disk, and that is on purpose

Here the protection ends, and you should know it beforehand. nexpaper does not encrypt the documents, neither the files nor the recognised text or the search index in the database. There is no encryption per person either. That is a decision, because it would make the search impossible and the files unreadable without nexpaper. The documents are meant to stay yours even on the day you stop using nexpaper.

What a personal vault means

Everyone has a personal vault that nexpaper shows to nobody else, the operator included, as long as the person does not share it. That holds for everything the app delivers: the search, the numbers and the lists. It does not mean that the files on the disk are unreadable.

Whoever runs the server can see the files

Whoever runs the server themselves can see the files there. Protecting the disk, with an encrypted drive for example, is the job of whoever operates the server.

Good to knowIn the app one way leads past a personal vault, in the open and leaving a trace: when the operator deletes an account, they choose where its documents go, themselves for example. The dialog says so, and the history of each document names who took it over.

What is sealed are the server's secrets: the provider's secret, the passwords of the mail server and the mailbox, the AI key, the Paperless-ngx token, the push key and the addresses of open links. The key for that lies as secret.key in the data folder, readable by its owner only.

Behind a proxy, with https

In the self-hosting example nexpaper can only be reached from the machine itself, at 127.0.0.1:8560. A reverse proxy that speaks https belongs in front of it. Whoever puts nexpaper into the home network without https sends passwords and codes across it in the clear.

Naming the proxy

NEXPAPER_TRUSTED_PROXIES names the address or network of the proxy. nexpaper believes only its word about the visitors' real address. Without it every sign-in seems to come from the proxy, and the protection against guessing cannot tell people apart.

Naming the address

NEXPAPER_PUBLIC_URL or the setting “Public address” names the address nexpaper is reached under. Invitation links, the return from the sign-in provider, passkeys and the contact for push come from it. nexpaper protects the cookies over https by itself; the proxy sends the HSTS header.

Rights on the server

Every request is checked on the server, in the query itself. A document, a sender or a vault that is not yours answers as if it did not exist, and no number gives away anything about what is not yours.

Strict headers

The page loads only files from its own server, no fonts, scripts or icons from others. The camera is for the page itself only, microphone and location are switched off. PDFs are shown in a sealed-off frame without network.

No root

The container runs with no-new-privileges and almost no capabilities, and nexpaper itself never runs as root. The start refuses a PUID or PGID of 0.

Other sites stay out

Every request from a browser that changes something carries a header that a page on another site cannot send.

A log without content

The log never holds a word from a document, a password, a key or a token, nor a search term.

Incoming files

A new document is opened only in a worker process of its own, with a time and memory limit and without the server's secrets. nexpaper does not call that a sandbox: the worker runs as the same system user as the server.

What goes out

The browser talks to your own server only. nexpaper brings its fonts, icons and scripts along; there are no statistics, no error reports, no maps and no self-update. The server itself makes only these connections, and most only once somebody switches them on.

ConnectionWhenOut of the boxWhat goes out
Question about a new versionwhen somebody opens “About nexpaper” and the last answer is older than a dayononly the question to GitHub, with no names, documents or settings. The operator switches it off with “Check once a day”.
Web Pushnotice of a new sign-in, export ready, Paperless import ready and similar occasionsonly once a device has signed upan encrypted message to the browser's push service (Google, Mozilla, Apple, Microsoft) that only the device can read. It never holds the content of a document.
AI servicefor each new document that still needs fields, once the operator has set up a serviceno AIthe recognised text of the first two pages, 6,000 characters at most, and the list of kinds. No picture, no account name. Personal vaults are left out from the start, and a daily limit of 200 requests applies.
Mail serverinvitation, link to reset a password, confirming an address, notices, test mailnone enteredaccount name, link, device and rough network, never the content of a document
Mailbox (IMAP)every 5 minutes, once the operator has switched it onoffthe sign-in to the mailbox, fetching, and afterwards marking, moving or deleting the mail
Paperless-ngxwhen looking and when an import runsnot set upthe API token, and it only reads. Paperless-ngx stays untouched.
Sign-in providerwhen one is set up and somebody signs in or links with itnot set upthe usual requests of OpenID Connect, no document
Setting up authentikonly when the operator presses “Set up”offcalls to authentik with a token that nexpaper does not store

Good to knowEvery address somebody enters (AI, mailbox, Paperless, push) is checked by nexpaper before each connection: resolved once, connected to exactly as checked, no redirect followed, and the addresses under which cloud providers offer their internal data are always blocked. A server in your own network has to be allowed explicitly first.

A backup is as confidential as a password

A backup of nexpaper is a ZIP file with the database, the settings and secret.key. The documents are not in it; they lie as plain files in /data/dokumente and belong in the backup your server makes anyway. The ZIP file is not encrypted. With the server's secret it lets you read the mail and AI credentials and the addresses of open links. Treat it like a password.

Downloading, uploading, deleting and restoring ask the operator for their password again, from a browser only. Before a restore nexpaper makes a trial run on a copy and says what would change, including which blocked devices, keys and links would be valid again. How it works is in the guide chapter Running it.

Reporting a security flaw

If you find a flaw, please do not report it in public but privately through GitHub: in the repository under “Security”, “Report a vulnerability”. It helps most to say what you found, how to reproduce it and which version ran.

An answer comes within a week. The fix goes out as a new version, and the release notes name the problem once the fix is there.

Security fixes go to the newest version only. Updating means docker compose pull and docker compose up -d; before a change to the database nexpaper makes a backup by itself. nexpaper never updates itself.

Security on GitHub