Vulnerability

Insecure Design
detect, understand, remediate

Insecure design (OWASP A04:2021) is the absence of a secure design pattern, a missing security control at the architecture level, or a threat-model gap that lets an attacker reach a result the application was never meant to allow. It is not an implementation bug; a perfectly coded implementation of a flawed design is still insecure.

No credit card required. Free plan available forever.

Severity

High

CWE ID

CWE-657

OWASP Top 10

A04:2021 - Insecure Design

CVSS 3.1 Score

8.1

What is insecure design?

Insecure design is the OWASP Top 10 category for vulnerabilities that exist because the security pattern was never modelled at the architecture stage, not because the implementation has a coding bug. OWASP added A04:2021 to capture the gap that the other Top 10 categories miss: an application can pass every static scan, every authenticated DAST, every dependency check, and still be insecure because the design left out a control the threat model required. The canonical CWE for the category is CWE-657 (Violation of Secure Design Principles), and the wider OWASP mapping spans dozens of design-stage CWEs including CWE-501 (trust boundary violation), CWE-522 (insufficiently protected credentials), CWE-602 (client-side enforcement of server-side security), and CWE-840 (business logic errors).

The shortest way to recognise insecure design: a perfectly clean implementation of a flawed design is still insecure. If the requirement document never specified a rate limit on the password-reset endpoint, no SAST rule will flag its absence; the code is doing exactly what it was asked to do. If the architecture diagram does not draw a trust boundary between the public marketing site and the internal admin API, no DAST run can recover the boundary the design forgot. Insecure design is what you get when a security requirement was never written, not when a written requirement was implemented incorrectly. That is the difference between insecure design (A04) and security misconfiguration (A05): misconfiguration is a deployment-stage failure of an existing control; insecure design is the upstream absence of the control itself.

The cost of an insecure design finding is higher than a typical implementation bug because the fix usually reaches into requirements, threat models, architecture diagrams, sequence flows, data flow diagrams, and the build of multiple services rather than a single source file. The right place to catch insecure design is the design phase: threat modelling, abuse-case analysis, secure design review, and a security-requirements pass before code is written. The next-best place is during early implementation, when authenticated DAST and code scanning surface the design omission as a runtime or static signal that can be traced back to the missing requirement. SecPortal supports both halves of that flow with code scanning against connected repositories, authenticated scanning across logged-in workflows, and a findings management record that carries CWE-657 design-level findings through retest the same way it carries CWE-89 SQL injection.

How insecure design surfaces

A04:2021 is a category, not a single flaw. The pattern is always the same: the threat model required a control, the design did not include it, the implementation does not have a bug, and the application behaves as designed all the way to compromise. The four canonical surfacing paths look like this.

1

Missing security requirement

No one wrote that the password-reset endpoint must rate-limit by account, the API must enforce per-tenant authorisation on every read, the checkout must reject negative line totals, or the file upload must size-cap before parsing. The requirement is absent, so the code never references it.

2

Missing trust boundary

The architecture diagram does not mark where untrusted input crosses into a privileged context. An internal admin API is reachable from a public health-check route. A customer-supplied JWT is trusted by a service that should re-verify it. Data flow crosses a boundary the design forgot to label.

3

Missing compensating control

A single control is expected to cover a risk it cannot cover on its own. The application relies on client-side enforcement, on a perimeter firewall, or on a CDN rule that downstream services treat as authoritative. The design did not budget for a defence-in-depth layer.

4

Missing abuse-case modelling

The design considered the intended user path but never modelled the abuse case: replay, race, mass-assign, parameter tamper, workflow skip, role-swap, or tenant escape. The implementation handles the happy path correctly and lets the abuse path through.

Common causes

No threat model for the change

The feature shipped without a structured threat model (STRIDE, PASTA, attack tree, or misuse-case enumeration). The team relied on coding standards and code review to catch design-level gaps, which is the wrong stage for that work.

No security requirements pass

The functional requirements were written but the security requirements (auth, authz, rate limit, audit log, input validation, encryption in transit and at rest, tenant isolation, abuse detection) were not enumerated and tracked alongside them.

Untracked design changes

A late-binding architecture change (a service split, a queue insertion, a new dependency) shifted a trust boundary without an updated threat model. The original review is now stale and the new boundary is undocumented.

Implementation-first culture

The organisation ships features first and reviews security later. By the time security gets the artefact, the design is set, the data flow is in place, and the cost of redesign is prohibitive. The flaw stays in.

Over-reliance on a single control

The design assumes WAF, CDN, perimeter firewall, or a third-party gateway will catch what application-layer controls do not. When traffic reaches the application through a side channel, the assumed control is not in path.

Missing tenant-isolation patterns

A multi-tenant application is designed with shared resources (database, cache, queue, file store) but without enforced tenant scoping in the query layer. The implementation is consistent with the design and still vulnerable to cross-tenant access.

How to detect it

Insecure design will not appear in a single dashboard the way SQL injection or XSS does. Detection is layered: a design-phase review surfaces the gaps before code; runtime and static signals surface the symptoms once code exists; and a finding-record discipline carries the design-level issue across teams without losing the trail back to the missing requirement.

Automated and tooling signals

  • SecPortal code scanning runs Semgrep rule packs against the connected repository for missing-authorisation, missing-rate-limit, missing-input-validation, and trust-boundary-violation patterns that often indicate a design-stage omission rather than a one-line bug.
  • Authenticated scanning walks the logged-in workflows and replays requests across roles, tenants, and step orderings to surface workflow-skip, parameter-tamper, mass-assign, and role-swap symptoms that map back to design omissions.
  • External attack surface enumeration discovers internet-facing routes that were not in the threat model (admin paths, debug routes, legacy subdomains, accidentally exposed buckets), each of which is a candidate trust-boundary breach against the original design.
  • Findings management tags scanner output against CWE-657 and the OWASP A04:2021 category so design-level findings are visible to the same owners who handle implementation bugs, with severity calibrated through CVSS 3.1 and the asset tier of the affected component.

Design-stage review

  • Run a structured threat model (STRIDE, PASTA, LINDDUN for privacy-heavy services, or attack tree for high-risk features) before any code is written, with explicit data flow diagrams that mark every trust boundary the change crosses.
  • Enumerate abuse cases alongside use cases: for every happy-path user story, write at least one misuse-case that names the abuser, the goal, and the assumed control. Track them in the same backlog so they cannot be dropped silently.
  • Walk the data flow with the team and ask whether each control is enforceable server-side, whether it survives a network rewrite, and whether a missing piece is being papered over by a perimeter device. If the answer is unclear, the design is not done.
  • Use the OWASP Application Security Verification Standard as a checklist for design-stage controls. ASVS Level 1 is the minimum for internet-facing applications; Level 2 is the default for applications handling sensitive data; Level 3 is for high-assurance contexts.

How to fix it

Write security requirements alongside functional requirements

For every feature, document the authentication, authorisation, rate limit, audit log, input validation, encryption, tenant isolation, abuse detection, and privacy requirements before implementation begins. Track them as first-class backlog items, not as a coding-standard appendix.

Run a structured threat model on every meaningful change

Pick one methodology (STRIDE is the most common; PASTA is useful for risk-driven prioritisation; LINDDUN is best for privacy-heavy services) and apply it consistently. Output is a current data flow diagram, a list of threats, and a list of agreed controls that maps to backlog items.

Adopt a reference architecture with secure defaults

Build a library of approved secure design patterns (authn middleware, rate-limit middleware, tenant-scoped repository, input-validation library, audit-log adapter) and require new services to compose from the library by default. The design phase becomes selection rather than invention.

Verify against OWASP ASVS and SAMM

Use ASVS as the design-stage checklist and SAMM as the maturity model that surfaces process gaps. A team that consistently fails the same ASVS chapter has a design-stage process gap, not a coder problem.

Treat insecure design findings as design-stage rework

When SecPortal records an A04:2021 finding, route it to the architect or design owner of record, not just the engineer who shipped the line of code. Capture the missing requirement in the threat model so the same gap does not recur on the next service.

Run paired AppSec and engineering retros after every incident

After an incident, ask whether the failure was an implementation bug or a design omission. If the bug was specified correctly in the design and miscoded, that is a coding issue. If the design did not specify the control, that is insecure design and the threat model is updated, not the codebase.

How SecPortal records and tracks insecure design findings

SecPortal is not a threat modelling tool and does not replace the design-stage review. It is the workspace where the design-level findings land alongside scanner findings and pentest findings so the same record holds severity, ownership, evidence, fix, and retest. The relevant flow for an A04 finding looks like this.

Record the finding with CWE-657 and CVSS 3.1

Capture the design omission as a finding on the engagement record, tagged against CWE-657 and the OWASP A04:2021 category, with a CVSS 3.1 vector that reflects the worst plausible exploitation path the missing control enables.

Attach the threat-model artefact as evidence

Upload the data flow diagram, the misuse-case write-up, the ASVS gap, or the SAMM finding through document management so the audit trail back to the missing requirement is on the finding, not in a separate share.

Route ownership to the design owner

Assign the finding to the architect, technical lead, or engineering manager who owns the design, not the engineer who wrote the implementing function. Insecure design fixes usually mean updating the design before the code.

Use code scanning and authenticated DAST as the symptom feed

Connect the repository, run Semgrep over the codebase, and run authenticated DAST against the running workflow. The scanner output is symptomatic evidence of the design gap and lands on the same finding record.

Track remediation through the same SLA model

Apply the standard severity-based remediation SLA. Insecure design findings often have a longer planning window than implementation bugs because the fix is upstream, but the SLA discipline is the same.

Retest after the design change ships

Pair the retest to the original finding through the retesting workflow. The retest is not just rerunning the scanner; it includes confirming that the threat model now names the missing control, the requirement is tracked, and the implementation references it.

Related vulnerabilities and recommended reading

Insecure design is the upstream root cause of a long list of more concrete vulnerabilities. The pages below cover the most common downstream symptoms, the frameworks that capture the design-stage controls A04 expects, and the SecPortal workflows that hold the findings record across the design, implementation, and retest stages.

  • Business logic flaws the design omission most often categorised as insecure design when the workflow lacks abuse-case modelling.
  • Broken access control the runtime symptom of a design that did not specify per-resource authorisation enforcement at the service boundary.
  • Mass assignment a property-binder pattern that ships when the design did not name a property allowlist for the serialiser.
  • Missing rate limiting the canonical example of a design control that was never written into requirements and never made it to the endpoint middleware.
  • Race conditions an abuse-case category that gets surfaced by a threat model that includes parallelism but not by one that stops at sequential happy-path flows.
  • Security misconfiguration (A05:2021) the adjacent category that captures a control which exists but is wrongly deployed; the design counterpart to A04.
  • OWASP ASVS the verification standard that lists the design-stage controls A04:2021 expects, chapter by chapter, at Level 1, 2, and 3.
  • OWASP SAMM the maturity model that names the design-stage process gaps a team has to close to stop generating A04 findings on every release.
  • NIST SSDF (SP 800-218) the federal Secure Software Development Framework with practice groups PO (Prepare the Organisation) and PS (Protect Software) that cover the design-stage controls a software supplier is expected to have in place.
  • Threat modelling guide the operational walkthrough for running STRIDE, PASTA, and LINDDUN reviews that catch insecure design before code.
  • Secure code review checklist the code-stage companion that confirms the design controls survived implementation.
  • NIST SSDF implementation guide the practitioner-side rollout narrative for moving design-stage discipline from policy to operating record.
  • SDLC vulnerability handoff the workflow that hands design-stage findings from AppSec to engineering owners without losing the trail back to the missing requirement.
  • Security onboarding for new applications the entry-stage process that catches insecure design on every new service before it ships its first release.
  • Code review the engagement shape that pairs design review with code review on the same engagement record.
  • SecPortal for AppSec teams the audience overview for the teams that own design-stage review across the application portfolio.
  • SecPortal for product security teams the audience overview for product security organisations that pair threat modelling with engineering work.

Compliance impact

Surface design gaps before they ship

SecPortal pairs code scanning and authenticated DAST against a connected repository, records design-level findings with CVSS 3.1 and CWE-657, and carries them through threat-model review, fix, and retest. Start scanning for free.

No credit card required. Free plan available forever.