Web application security: the basics almost no one does
Security rarely fails for lack of available technology. It fails because of small decisions made in a hurry: an endpoint without a resource-owner check, a field accepted without validation, a key committed to a configuration file. This article describes the minimum set of practices that, applied with discipline, eliminates most of the incidents that show up in practice.
Authentication answers who; authorization answers what
Confusing the two is the source of an entire class of failures. Authenticating means confidently establishing the identity of whoever is calling. Authorizing means deciding, for each concrete resource, whether that identity can read or change that specific piece of data.
In practice, the most common failure is authorizing by route rather than by record: the system checks that the user is logged in, but not that the request actually belongs to them. That check must happen on the server, as close to the data as possible — in database rules when the platform offers that feature.
- Every sensitive query filters by the authenticated user's identifier, never by a parameter coming from the client.
- Roles live in their own table, never in an editable profile field.
- Access rules are tested like any other business rule.
Input is hostile by definition
Every piece of information coming from outside — form, query string, header, webhook, uploaded file — must be treated as potentially malicious until validated against an explicit schema. Validating means accepting only what is expected, not trying to strip out what is dangerous.
The same recommendation applies to output: data rendered in the interface must be handled according to the context where it appears, and database queries should always use parameters, never string concatenation.
Secrets, dependencies and exposed surface
API keys and credentials belong to the server environment, with planned rotation and restricted access. If a key can be read by the browser, it should be treated as public and given permissions accordingly.
Dependencies deserve the same care: a known inventory, periodic updates and automatic vulnerability checks in the pipeline. Much of the exploited surface in production lies in outdated libraries, not in custom code.
- Security headers configured: content policy, origin isolation and mandatory secure transport.
- Request rate limits per identity and per origin to contain automated abuse.
- Logging of sensitive events with date, origin and outcome, preserved for auditing.
Incident response is part of the system
No defense is perfect, so the project needs to plan for the bad day: how to revoke sessions, how to rotate keys, how to determine the scope of a leak and how to notify those affected. An organization that has rehearsed that playbook turns an incident into an inconvenience; one that never thought about it turns the same event into a crisis.
In short
Sustainable security is routine, not heroics: validate input, authorize by resource, protect secrets, update dependencies and rehearse incident response.
Use cases
Portal with data from multiple clients
Isolation by organization enforced at the database level, so a poorly written application query can't leak data across accounts.
Public API with partner integrations
Per-partner keys, minimal scopes, usage limits and verified signatures on every incoming webhook.
Admin area
Mandatory second factor, short sessions, audit trail and lockout after invalid attempts.
Common mistakes
- Relying only on validation done in the browser.
- Storing the admin role in a field the user themselves can edit.
- Exposing error messages with internal database detail or stack traces.
- Treating security as a final step, done after delivery.
Best practices
- Least privilege at every layer: database, API, integrations and people.
- Schema-based validation at the edge, with explicit types.
- Secrets kept out of the repository, with documented rotation.
- Automated tests for access rules, not just for business rules.
Recommended books
The Web Application Hacker's Handbook — Dafydd Stuttard and Marcus Pinto
Shows how applications are actually attacked, which changes how you design defenses.
Threat Modeling — Adam Shostack
A structured method for anticipating risk before writing code.
Security Engineering — Ross Anderson
A solid conceptual foundation for why secure systems fail in practice.
Frequently asked questions
- What's the difference between authentication and authorization?
- Authentication establishes who the user is. Authorization decides what that user can do with each specific resource.
- Do I need a second factor on every system?
- In admin areas and any access to sensitive data, yes. It's the measure with the best ratio of effort to risk reduction.
- Isn't front-end validation enough?
- No. It improves the experience, but it can be bypassed. The validation that protects the system is the one on the server.
- How do I know if my dependencies are vulnerable?
- With automatic checks in the pipeline and periodic review of versions, licenses and active maintenance of packages.
- How much does it cost to build in security from the start?
- Much less than fixing it later. Reworking authorization and modeling is one of the most expensive overhauls in software.