Secure by default: how I build web apps people can trust
The habits and defences I use on every project: short sessions, strict validation and uploads that are guilty until proven innocent.

Joshua Adjei
· 1 min read
Security is easiest when it is part of the design rather than a checklist at the end. This is how I approach it on the web apps I build, from the first route to the last deploy.
Start with the threat, not the tool
Before picking a library, I write down what could go wrong: someone guessing an admin URL, a stolen session, a malicious file upload. Each risk gets one clear defence, and each defence gets a test.
Sessions that expire on purpose
- Short-lived access tokens kept only in memory.
- A refresh token in an HttpOnly, Secure, SameSite cookie that JavaScript never sees.
- Rotation on every refresh, so a stolen token works at most once.
A session you cannot revoke is a session you do not control.
Validate at the edge
Every request body is parsed against a schema before it reaches a service. Unknown fields are rejected, lengths are capped, and URLs must be https.
const body = createCommentSchema.parse(await request.json());
Uploads are guilty until proven innocent
Files go to a private staging area first, are checked, and only then become public. Nothing the visitor sends is ever served from the same origin without that step.
Small habits that add up
- Rate-limit anything that sends email or creates accounts.
- Compare secrets in constant time.
- Log decisions, not personal data.
None of this is exotic. Done consistently, it is what makes an app trustworthy.
Comments6