Security & privacy

This app touches two sensitive things: your receipts and your Splitwise account. Here is exactly what happens to both, in plain terms.

Your Splitwise account

Your Splitwise password never touches this app. Signing in happens on Splitwise’s own site; the app only ever receives an access token.

That token is kept in a cookie that is encrypted (AES-GCM), readable only by the server, never by JavaScript, and never written to the database or sent back to the browser. It expires after 24 hours. Signing out deletes it.

Nothing is created, changed or deleted in Splitwise unless you press the button that says so. Deleting a shared expense always asks first, because it affects everyone in it.

Your receipts

Photos are stripped of location data in your browser, before upload, and again on the server for JPEGs — so GPS never survives even if the browser step fails.

The image is sent to Google Gemini to read the items. That is the only place receipt contents leave this app. The raw text it returns is discarded.

If you are signed in, your split and its photo are saved under your Splitwise account only: a private storage bucket with no public URLs, an ownership check on every single read and write, and row-level security in the database that denies everything by default. Signed out, nothing is stored.

A share link is the one exception, and only when you make one. On a saved split you can create a read-only link. Until you do, there isn’t one. While it exists, anyone holding that link can read that one receipt and see its photo without signing in — so treat it like the receipt itself and only send it to people who were on the bill. The link is a long random address that cannot be guessed or found by search engines, it opens nothing else in your account, and it can never change anything.Turn off link kills it instantly for everyone, and removing the split removes the link with it.

When you remove a split, the receipt is destroyed: items, merchant, date, names and per-person amounts are overwritten and the photo is deleted from storage. One anonymous line stays in the usage totals — amount, currency, and how many items and people — which cannot rebuild the receipt and is not linked to anything you can be identified by. That is the app’s own record of work done, and it is the only thing kept.

How the app itself is protected

  • Every request is checked. Reads and writes filter on both the record id and your account id, so one person’s link cannot reach another person’s split. The only reads that work without a signed-in account are share links you created yourself, and each opens exactly one receipt.
  • Secrets stay on the server. The database service key and the Splitwise client secret are never sent to the browser.
  • Uploads are verified. File type is checked by reading the bytes, not trusting the name, and size is capped.
  • Input is validated on the server before anything is sent to Splitwise, and the split is recalculated there — the browser’s totals are only a preview.
  • Rate limits on reading receipts, creating expenses, and signing in to the admin area, so the free quotas can’t be burned by one visitor.
  • Browser protections: a content security policy, HSTS, no framing, no MIME sniffing, and a strict referrer policy.
  • Admin access is a username and a salted, hashed password (scrypt), an encrypted session that expires in 8 hours, lockout after repeated failures, and a one-time reset link by email. Admin sees counts only — never receipts, names or amounts.

What this app does not do

No ads, no trackers, no analytics company, no selling anything to anyone. Usage numbers are counts kept in this app’s own database, under a keyed pseudonym.

It is not a bank and stores no card details. It never asks for a password belonging to another service.

Found a problem?

Please report it privately first: gaurav.inbox29@gmail.com. You’ll get a reply. Machine-readable details are at /.well-known/security.txt.

One person runs this app, honestly, for free. If something here stops being true, this page changes with it.