Insecure Design: The Flaws You Cannot Patch
Insecure Design is one of the new categories introduced in the 2021 Top 10, and it marks a shift in where OWASP looks for risk. Every other item on the list describes a flaw in implementation — a missing check, a weak cipher, an unsanitised input. A04 describes a flaw in the design itself: a system that would be insecure even if every line of code were written flawlessly, because the threat was never considered.
OWASP is careful to distinguish insecure design from insecure implementation. A secure design can be undone by a bad implementation bug. But an insecure design cannot be rescued by perfect implementation — there is no code fix for a missing control that was never specified. The workflow simply lacks the defence, and no amount of careful coding will add one that was never designed in.
What a design flaw looks like
Consider an account-recovery flow built entirely on knowledge-based questions — mother's maiden name, first school — all of which are discoverable or guessable. Each individual line of code may be correct: the input is validated, the query is parameterised, the answer is compared safely. The flaw is architectural. The design chose a weak authentication factor, and no implementation quality can compensate for that choice.
- Missing rate limits by design. A workflow that never contemplated abuse — no throttle on password resets, no limit on ticket purchases — invites automated exploitation.
- Trust placed in the client. A checkout that calculates the price in the browser, or a mobile app that assumes it is the only caller of its API.
- Business-logic gaps. Flows that can be run out of order, skipped, or replayed to reach a state the designer never intended.
- Insufficient separation. A single tier trusted to enforce rules that a determined user can simply route around.
# server accepts the client's price instead of looking it up — a design flaw, not a bug
Designing securely
- Threat-model early. Before building, ask what could go wrong with each flow and who benefits from abusing it. Document the trust boundaries.
- Use a secure development lifecycle that includes design review, not just code review, with security involved from the requirements stage.
- Write and reuse secure design patterns — a hardened authentication library, a vetted payment flow — rather than reinventing sensitive logic each time.
- Enforce business rules server-side and never trust the client to be the only caller or an honest one.
- Write abuse cases alongside use cases, and test that the system resists them, not just that it satisfies the happy path.
Insecure design is the hardest category to retrofit, because fixing it often means redesigning a live system rather than patching a line. The cheapest time to catch it is before anything is built — which makes the discipline of asking "what did we assume, and who could break that assumption?" the most valuable habit on this entire list.
- Take one critical flow (password reset, funds transfer, role change) and ask: if every field were valid but the user were hostile, what could they achieve? Design flaws survive perfect input validation.
- Check whether abuse cases were ever written down alongside the features. If the threat model is only in someone's head, the gaps are too.
The full, at-scale version — threat-modelling each flow for the logic and trust-boundary flaws that no scanner and no input filter will ever catch — is what our assessment (and SecStudio agents) runs for you.