6The body must match a strict schema, or it’s refused.
7Values reach Postgres as parameters, never as SQL.
Script injection
Stopped at the outer wall
Getting your browser to run someone else’s JavaScript on kodeo.website — to read the page or act as you.
Every page carries a Content-Security-Policy with a fresh random nonce per request: a script without it never runs, and `unsafe-eval` is not allowed anywhere.
Anything people write — names, comments, chat, Markdown, AI answers — is rendered as text or through our own parser, never as raw HTML.
Project files are only ever sent as downloads (`Content-Disposition: attachment`, `nosniff`, a sandbox CSP), so an uploaded .html or .svg can’t execute here.
Forged requests
Stopped at the first post in the courtyard
Another site making your browser send a request to KODEO — while you’re signed in — that you never meant to send.
Every request that changes something must come from our own origin: the `Origin` header is checked, and so is the browser’s `Sec-Fetch-Site`.
Bodies are JSON, which another site can’t send across origins without a preflight we never approve.
Sign-in cookies are `SameSite`, and the Console’s are `SameSite=Strict` with a custom header on every action.
Stolen session
Stopped at the second post
Taking a copy of your signed-in cookie and using it from somewhere else.
Session cookies are `httpOnly` and `__Host-` scoped: the page’s own scripts can’t read them (the check further down this page shows it).
The access token lives 15 minutes. The refresh token rotates on every use — replaying an old one is detected, and the whole session family is ended at once.
Every device is listed in Settings → Sessions with its full address; one tap ends it, and “This wasn’t me” ends all of them.
Password guessing
Stopped at the gatehouse
Trying leaked or common passwords against accounts, fast and at scale.
Passwords are stored only as Argon2id hashes (19 MiB memory, 2 passes) — slow and memory-hard by design.
Attempts are rate-limited per address and per account, with a temporary lock after repeated failures; staff can block an address outright.
Two-factor (an authenticator app or a passkey) means a right password alone still doesn’t open the account — and a new device is emailed to you.
Phishing page
Stopped at the gatehouse
A convincing copy of the sign-in page that collects what you type.
Passkeys are bound to kodeo.website by your device: a look-alike domain simply can’t ask for them.
Sensitive actions ask you to confirm it’s you again (“step-up”) — with two-factor on, an emailed code alone is never enough.
A sign-in from a new device sends you an alert with a one-tap “This wasn’t me”.
SQL injection
Stopped at the vault door
Smuggling database commands inside ordinary input — a search box, a name, a file path.
Every query is parameterised: values travel separately from the SQL text, so input can never become a command. Nothing is string-built.
Input is checked against a schema before it reaches a query, and file paths go through one validator that refuses traversal, control characters and reserved names.
Each change runs in a transaction with the right locks, so a half-applied write never exists.
Malicious project
Stopped at the moat
Code inside a project — yours, a teammate’s, or a cloned repository — trying to reach your KODEO account.
Code runs in your own browser tab (WebContainers), in a frame on a different origin — it can’t read KODEO’s cookies, pages or storage.
Only the editor is cross-origin isolated, and a running app is shown in a sandboxed frame; nothing a project prints is ever served from kodeo.website.
Files written by a run come back only through checks on the server: your role, the path validator, the plan’s limits, binary detection.
Token theft
Stopped at sealed inside the vault
Getting hold of your GitHub access, or the secret behind your two-factor codes.
GitHub tokens are encrypted with AES-256-GCM under their own key, bound to your account, and used only on the server — no route ever returns one.
Two-factor secrets are sealed the same way; backup codes, reset links and recovery codes are stored only as hashes.
Commits are scanned for secrets before they’re made, and exports never include tokens or other people’s email addresses.
Realtime server breach
Stopped at the broken bridge
Taking over the live-collaboration server and using it to reach the database.
The collaboration server holds no database credentials at all: every read and write goes through one HMAC-signed endpoint with a replay window.
Membership is re-checked on each call, and permissions are checked per message — a viewer’s edits are dropped on the server.
Removing someone from a workspace ends their live connection at once.
Rogue insider
Stopped at the watchtower
Someone with staff access abusing it — or someone who took over a staff account.
Staff need two locks — a staff record and an address on a list held outside the database — and a separate Console session that ends after 15 idle minutes.
Dangerous actions need a passkey from the last five minutes, and a key added in the last 24 hours can’t confirm them.
Everything staff do is written to an append-only, hash-chained audit log that the database itself refuses to edit. Personal details are masked by default.
Payment tampering
Stopped at the treasury
Faking a successful payment — or changing the amount — to unlock a paid plan.
A plan changes only when Cashfree’s signed webhook (or our own call to Cashfree) says so — never on a redirect or anything the browser sends.
Prices come from the server; amount or currency mismatches are never credited, and every transition is idempotent inside a transaction.
Card details are entered on Cashfree’s page. KODEO never sees them.
Your side of it
Thelocksyouhold.
Everything below is in Settings, and each takes under a minute. A passkey and a second factor stop almost every account takeover there is.
Your data moves one way: from your browser, through the app, into the database. The live-collaboration server sits beside that path, never on it.
Your browser
Your code runs here
Run, the terminal and Python execute in your own tab, in a frame on another origin.
Nothing you run executes on KODEO’s servers
Previews are sandboxed frames
Your dependency cache stays on this device
Singapore · Vercel
The app
Every page and API call, next to the database — HTTPS only, a fresh CSP nonce per page.
Functions pinned to one region (sin1)
Every change checked for origin, session and schema
No card details — ever
Singapore · Neon Postgres
Your data
Files, Git history, accounts and billing, in Postgres — reached only through parameterised SQL.
Encrypted at rest by the provider
Secrets sealed again with AES-256-GCM
Passwords only as Argon2id hashes
Mumbai · Oracle Cloud
Live collaboration
The server that carries cursors and edits between people — with no way into the database.
No database credentials at all
Every call to the app HMAC-signed
Terminal output never stored
The services we rely on — Vercel, Neon, Oracle Cloud, Cashfree, our email provider, and DeepSeek for KODEO Assist — and exactly what each receives are listed in the Privacy Policy.
Don’t take our word for it
Checkityourself.
Your browser just received this page. Here is what came with it — read live, in your browser, right now. Anyone can run the same check with their browser’s developer tools.
Reading this page’s headers…nothing leaves your browser
Every part, a layer
Securitywasn’taddedlater.
KODEO is built in numbered parts, and each one shipped with its own defences — and the tests that prove them.
A separate Console: two locks, passkey step-up, 24-hour probation for new keys, a hash-chained audit log.
Part 8.5
An AI that never sees your code
KODEO Assist scrubs personal details, filters its own output, and reads your account only with consent.
Part 8.6
This page, and security.txt
A public account of how it all works, checks you can run yourself, and a clear way to report a problem.
Responsible disclosure
Foundacrack?Tellusfirst.
In scope
www.kodeo.website — the app, its API and the Console at /admin
collab.kodeo.website — the live-collaboration server
How KODEO handles your data, tokens, sessions, files and payments
Please don’t
Access, change or delete anyone else’s data — use your own accounts and workspaces to test
Run denial-of-service, load or spam tests, or brute-force sign-in beyond what shows a rate limit works
Social-engineer staff or users, or test physical security
Test the services we use (Vercel, Neon, Oracle, Cashfree, GitHub, DeepSeek) — report to them directly
What we promise
A human reply within 48 hours, and updates until it’s fixed
Public credit for a confirmed issue, if you’d like it
That we won’t pursue legal action for research done in good faith and within these rules
That you can publish 90 days after we confirm the report — sooner once it’s fixed
A good report has
What you found and where — the page or the API route
Steps to reproduce it, and what an attacker could do with it
Your account’s email (never your password), so we can match what we see
Questions
Asked,andansweredplainly.
Can KODEO staff open my code?
The Console — the only place staff work — has no way to open your files or your editor. What it does show (your plan, your usage, your sign-in methods) is masked by default, revealing an email address needs a written reason, and every action is written to an audit log that can’t be edited. Direct access to the database is limited to the owner’s own credentials; like any service, that is the one place trust sits, which is why it is kept that narrow.
Is my code used to train AI?
No. KODEO Assist never receives your files, code, errors or terminal output — in the editor it’s given state only (which panel is open, whether a run is going). Questions are cleaned of email addresses, phone numbers, codes and anything shaped like a secret before they’re sent.
My laptop was stolen. What do I do?
Sign in from another device and open Settings → Sessions: end that device’s session, or tap “This wasn’t me” to sign every device out and start a password reset. If you had passkeys on it, remove them in Settings → Security.
How are passwords stored?
Only as Argon2id hashes (19 MiB of memory, 2 passes, parallelism 1) — a deliberately slow, memory-hard function, so a copy of the database doesn’t turn into a list of passwords. Better still, use a passkey: then there’s no password to steal.
Does KODEO store my card?
No. You pay on Cashfree’s own page; KODEO receives only the outcome, and a plan changes only when Cashfree’s signed message says so.
What happens to my data if I delete my account?
Recurring payments are cancelled first, then your account, the workspaces you own and their files are deleted in one transaction. Workspaces you were only a member of stay with their owners.
Readywhenyouare.
A workspace, a project and a live editor in under a minute. Free, no card.