OWASP Top 10:2021 — A04: Insecure Design
Welcome to Part 4 of our OWASP Top 10:2021 series. So far, we’ve looked at hands-on, tactical flaws like Injection and Cryptographic Failures. But now we’re going up a level.
This time, we’re looking at Insecure Design — a category that’s more about how software is architected than how it’s coded. This risk focuses on the absence of secure design principles, not just implementation bugs.
If the app was designed insecurely to begin with, all the patches in the world might not save it.
Full series:
- A01: Broken Access Control
- A02: Cryptographic Failures
- A03: Injection Attacks
- A04: Insecure Design (you are here)
- A05: Security Misconfiguration
- A06: Vulnerable and Outdated Components
- A07: Identification and Authentication Failures
- A08: Software and Data Integrity Failures
- A09: Security Logging and Monitoring Failures
- A10: Server-Side Request Forgery (SSRF)
What is Insecure Design?
Insecure Design refers to flawed architectural decisions or workflows that create security risks, regardless of how well the code is implemented.
This could include:
- A file upload feature with no limits on file type or size.
- A business logic workflow that allows a user to cancel a payment after receiving goods.
- A system that doesn’t log sensitive actions or support audit trails.
- A lack of rate limiting on a login form or password reset endpoint.
Even if the code does what it was designed to do, the design itself is unsafe.
Why Does This Happen?
The root causes are often:
- Security not being part of early planning discussions.
- Pressure to ship features before threat modeling.
- Underestimating how creative attackers can be with logic abuse.
- Overly permissive flows that favor UX over risk controls.
Security is a process, not just a feature. If it’s not considered during planning, it’s too late when the code is already written.
How Attackers Exploit Insecure Design
Let’s look at some real-world-ish examples:
Business Logic Abuse
A rewards system lets users refer friends for credit — but doesn’t validate who gets referred. An attacker writes a script to refer themselves hundreds of times with fake accounts.
Result: free money.
Unrestricted File Upload
You allow users to upload PDFs, but don’t enforce file type validation. An attacker uploads a .php file disguised as a .pdf, then accesses it through a browser.
Result: remote code execution.
Insecure Workflow
A system allows a user to request a refund without verifying whether the original payment was completed.
Result: the attacker gets money back on an order they never paid for.
What Engineers Can Do
This is where proactive thinking beats reactive patching. Here’s how to design more securely from the start:
- Do Threat Modeling Early
- Ask: What could go wrong?
- Consider attacker perspectives during design: how might they abuse or chain features?
- Use STRIDE or similar frameworks to uncover design-time risks.
- Apply Secure Design Patterns
- Enforce least privilege: users should only access what they need.
- Implement defense in depth: don’t rely on a single control to protect sensitive actions.
- Use input validation and output encoding everywhere — not just where you expect input.
- Design for Abuse Cases, Not Just Use Cases
- Think beyond the happy path. What happens if someone tries to:
- Resubmit a form twice?
- Skip steps in a checkout flow?
- Send unexpected parameters?
- Incorporate Security into UX Design
- Don’t trade safety for convenience. Add friction where it matters:
- Email confirmation before changing sensitive settings.
- CAPTCHAs or throttling on login or reset forms.
- Strong password requirements and two-factor authentication (2FA).
- Log and Monitor Security-Sensitive Events
- Include audit trails for admin actions, auth events, data changes.
- Design the logging into the architecture, not as an afterthought.
Real-World Example: Race to the Refund
Imagine you’re building an e-commerce system. A customer can click “Cancel Order” for a refund — even if the order was already processed and the product shipped.
The system wasn’t broken — it behaved exactly as designed. But now your refund budget is bleeding dry because users figured out how to game the workflow.
This is insecure design in action: the business logic allows abuse that code-level patches can’t fix.
Final Thoughts
Insecure Design is the hardest of the OWASP Top 10 to fix because it’s the one that starts before the first line of code is written. But it’s also where you can have the most long-term impact.
Fixing a bug is a sprint. Designing for security is a marathon.
Up next: A05: Security Misconfiguration → We’ll look at how small mistakes in settings, permissions, and environments can open the door to big compromises.
Leave a comment