Security
If you have found a way to break something here, this page tells you where to send it and what happens next. It also tells you, plainly, what we have and have not done.
Where to send it
Tell us what you did, what happened, and what you expected instead. A short proof of concept is worth more than a long description. Screenshots are fine. We read everything.
We aim to acknowledge a report within three business days. This is one person and a small site, not a security team with a rota, so that is a target rather than a guarantee. If a week goes by with no reply, send it again to Hello@ObscuraOS.com.
The machine-readable version of this is at /.well-known/security.txt.
What the threat model actually is
There is no account system and no server that holds your documents. The tools are HTML, CSS and JavaScript, and they run in your browser on files you open from your own disk. That removes most of the categories a normal web application worries about. There is no session to steal, no database to dump, no password to reset, and no server-side view of what you were working on.
What it leaves is the browser, and that is where a real problem would live:
- A path that makes a tool send the file it is working on anywhere at all, deliberately or by accident.
- A way past the content security policy, which is what stops a third party script running on these pages.
- Script injection through something that looks like data: a document name, a pasted document, a filename, a value in an uploaded CSV or PDF.
- A flaw in how a vault is encrypted, or in how a passphrase is turned into a key.
- Something written to storage that should not persist, or that persists across what should be a clean session.
- A cell in a CSV the site writes that a spreadsheet would run as a formula. Every one is meant to go out with an apostrophe in front of anything that begins =, +, - or @.
There is a small server side too, and it is in scope: the route that serves the paid applications’ code only to a paid key (/pro-code/), the routes that make and renew keys and send the sign-in email (/api/licence, /stripe-webhook), the seats console (/api/seats) and the waitlist. A way to get the paid code or a key without paying, to read somebody else’s seats, or to make the site email somebody who did not ask, is a report we want.
Those are the reports we want. You can check the first one yourself in about a minute: see how to verify that nothing is uploaded.
What is in place
- An enforcing content security policy. Not report-only. Scripts, styles, images, fonts and connections are limited to this origin, object-src is none, and base-uri and form-action are pinned to this site so an injected tag cannot redirect a form or rewrite relative URLs.
- No third-party JavaScript, with one exception: Cloudflare’s analytics beacon, which counts page views and sets no cookie. Every library the tools use is served from this domain rather than a CDN, so a compromise of someone else’s CDN cannot become a compromise of these pages.
- No accounts, and no session to steal. Nothing to hijack. The one cookie, for Pro subscribers, holds a signed key that is sent only to the Pro code route; it opens nothing but that code, and a stolen one stops working when its date or the subscription ends.
- Permissions denied by default. Payment, USB, serial and Bluetooth are switched off at the header level for the whole site. Camera, microphone and location are allowed for this origin only, never for anything embedded, and only a few tools ask, on a press and through the browser’s own prompt: the camera in AIRGAP, SNAP and REEL, the microphone for a voice-over in REEL, and location in CORDON, SNAP and MILEAGE.
- HSTS, nosniff, framing limited to this origin, and a referrer policy that does not leak the page you came from.
Business and Team: seats
On Team and Business, whoever holds the key the subscription came with can give each person a key of their own on the seats page, and take it back. This is the one place the service keeps anything about people other than the buyer, so here is exactly what it is:
- What is kept. Each person’s name and email address as the admin typed them, the dates they were added, joined, last had their key renewed and were removed, and a record of every change with the fingerprint of the key that made it. It is held in Cloudflare Workers KV, in our own account. Nothing about what anybody opens or does with the tools is kept, because none of it reaches the server.
- Who can read it. Only a request carrying the subscription’s own key, signed by us, in date and for a subscription Stripe says is paid. Anything else gets the same 404 as a page that does not exist, and wrong keys are rate limited.
- Invitations. 32 random bytes, used once, run out after fourteen days, and stored only as a SHA-256 hash. The token travels after the # in the link, so it is never sent to a server in an address or a referrer.
- Taking a seat back. A person’s key runs 35 days at most and renews only while their seat is there. Once removed, their key is refused by the Pro code route within about two minutes wherever they are online; a device kept offline keeps working until its key runs out.
- A shared key. A team that shared the subscription’s key can replace it once everybody has a seat; every earlier copy then stops working and cannot be renewed.
The terms for this data are in the data processing agreement.
What is not in place
This is the part most sites leave out, so here it is.
- No third-party security audit. Nobody independent has reviewed this code. If that matters for your use, it should count against us.
- No paid bug bounty. We cannot pay for reports. We will credit you by name on this page if you want the credit, and we will say what you found.
- No SOC 2, no ISO 27001, no penetration test report. If your procurement process needs one of those, we do not have it and we are not going to pretend otherwise.
- No SSO or SCIM. People are added to a plan by name and email address, one at a time or from a CSV file.
- No formal service level agreement. See the response target above for what we can actually commit to.
The argument for using this is not that it has been certified. It is that the software runs on your machine and you can watch it not talk to us.
If you are looking
Test against your own browser and your own files. Do not test against another person’s data, and do not run anything that degrades the site for other visitors: no load testing, no automated scanning at volume, no denial of service.
Give us a reasonable chance to fix something before you publish it. Ninety days is the convention and it is fine by us; if the fix lands sooner, publish sooner.
If you stay inside that, we will not pursue legal action against you or ask anyone else to. Finding problems in this is a favour, and we intend to treat it as one.
Related: verify that nothing is uploaded, incident response and breach notification, sub-processors, the CAIQ, answered, business continuity, privacy, data processing agreement, acceptable use.