Kartik Kant / All lessons Chapter 4 · Getting it out there
Lesson 4.2

The security stuff you can't skip

Security writing tends to be either terrifying or so detailed you close the tab. Neither helps when you're shipping your first app.

For a small app with a normal amount of users, there's a short list that covers most of the real risk. Everything beyond it can wait until you have something worth attacking.

Secrets don't go in the app

A secret is any key or password that lets your code do something privileged. Your payment provider's private key. Your database admin credentials. An AI API key you're paying per request for.

The rule: anything running in the browser or shipped inside a mobile app is public, no matter how well hidden it looks. People can read it. "Minified" and "compiled" are not hiding places.

Secrets live on a server, or in your hosting provider's environment settings. Never in your frontend code, and never committed to git, because git remembers forever even after you delete the line.

If you do accidentally commit one, deleting it isn't enough. You have to assume it's compromised and generate a new one. There are bots doing nothing but scanning public repositories for keys, and they are fast.

Anything public will be abused

Any address on the internet that accepts input will eventually be found and poked at, usually by automated scripts rather than a person with a grudge.

Which means anything public needs a limit on how often it can be used. Without one, a single script running in a loop can exhaust whatever it touches: your sending quota, your AI budget, your database.

The specific version worth understanding: if you have a form that sends an email, and it has no limits, somebody can use it to send email to whoever they like, from your domain. That's an open relay, and the damage isn't just the bill. Your domain gets flagged as a spam source, and then your real emails stop arriving anywhere.

A rate limit and a hidden field that bots fill in and humans don't will stop most of it. Both take about fifteen minutes.

Check permissions on the server

The most common beginner mistake, and it's easy to make because the app looks correct.

If a user shouldn't see something, hiding the button doesn't achieve anything. The server will still answer if somebody asks it directly, and asking it directly means opening the browser's developer tools, which is not a hacking skill.

Every check that matters has to happen where the data lives. The interface is a convenience for honest users, not a security boundary.

Tools like Supabase have this built in: you write a rule saying people can only read rows they own, and the database enforces it regardless of who's asking or how.

Never trust what comes in

Anything a user sends you should be treated as potentially hostile, not because your users are hostile, but because one day someone will be.

The two classic problems both come from taking input and using it as instructions rather than data. Sending user text straight into a database query lets them rewrite the query. Putting user text straight onto a page lets them run code in another user's browser.

Modern tools handle most of this for you if you use them normally. The danger zone is when you construct things by gluing strings together. If you find yourself building a query or some HTML by concatenating user input, that's the moment to stop and ask.

Don't collect what you don't need

The quietest security measure available.

Data you never collected can't leak, can't be stolen, and doesn't need protecting. Every extra field you store is a small ongoing liability, and most apps collect things "in case they're useful later" that never get used at all.

Fewer fields, less risk, less to explain in your privacy policy. Which is the next thing.

Not legal advice, just the shape of it.

If you collect anything personal, and an email address counts, you need a privacy policy, and app stores require one before they'll list you. It has to honestly say what you collect, why, who else sees it, and how someone deletes it.

The important part is that it matches what your app actually does. A policy claiming you collect nothing while your app quietly sends analytics is worse than having no policy, because now it's a false statement rather than an omission.

Worth knowing: adding a library can change what your app collects without you noticing. Some SDKs gather device identifiers by default just by being present. So the honest answer to "what do we collect" is about what ships in your app, not just what you wrote.

A quick story. Early in my career I got the security layer wrong on a health project. Health data, so about as sensitive as it gets.

I found out, and then spent two days more or less without sleep fixing it, testing it, and getting it into production. I remember the specific feeling of those two days quite well.

You don't have to learn it that way. That's genuinely the point of this lesson. The list above is short, and working through it before you launch takes an afternoon. Working through it after something has gone wrong takes considerably longer and feels much worse.

If you want a security review

Work this chapter with Claudea prompt to run on your own project
I've built an app and I want to check for obvious security problems before launching. I'm new to this, so explain each issue in plain words and tell me how serious it actually is. What my app does: [describe it] What data it stores about people: [list it] Anything public that accepts input: [forms, endpoints, uploads] Please act as a reviewer trying to find problems, not to reassure me. Check: 1. Whether any secrets or keys could be exposed in the frontend or in git. 2. Whether public forms or endpoints could be abused in a loop, especially anything that sends email or costs money per request. 3. Whether permissions are enforced on the server rather than just hidden in the interface. 4. Whether I'm collecting personal data I don't actually need. For each problem, tell me the realistic worst case and the fix.
Open Claude ↗

Asking it to look for problems rather than confirm things look fine changes the answer noticeably. Try both once and you'll see what I mean.


Next: Putting it on the internet →

Go deeper: Chapter 30, Security and Code Review and Chapter 40, Privacy, Terms and Compliance

Useful? Share this lesson