Accueil / retour à la liste

Insecure Design

4) Insecure Design

What it is (simple)

Insecure Design means the system idea/workflow is unsafe, even if code is clean.

This is different from a coding mistake:

  1. Coding bug: “we wrote this check wrong.”
  2. Insecure design: “we never planned this check/control at all.”

So the app behaves “as designed,” but the design itself is weak.


Easy mental model

Think of building a house:

  1. Code bugs = broken lock on the door.
  2. Insecure design = no door in the first place.

Common insecure design examples

  1. No rate limit on login or OTP verification.
  2. Password reset flow does not expire tokens quickly.
  3. Money transfer flow allows negative values or replay.
  4. API allows changing account owner because workflow trusts client too much.
  5. Admin actions need no second confirmation or step-up auth.
  6. Multi-tenant app has no tenant isolation strategy at design level.

Step-by-step attack example (password reset design flaw)

  1. App has “Forgot password.”
  2. It sends reset token by email.
  3. Token is valid for 7 days and can be reused many times.
  4. Attacker steals old email/token once.
  5. Days later attacker reuses same token.
  6. Account is taken over.

Problem is not just one line of code. Main problem: token lifecycle was designed poorly (long lifetime + reusable).


Why this happens

  1. Team focuses on features first, abuse later.
  2. No threat modeling during planning.
  3. No “abuse-case” testing.
  4. Assumption: “authenticated user = safe user.”
  5. Security requirements were never written.

Tricky concepts explained

1) Threat modeling

Threat modeling means asking early:

  1. What are we protecting?
  2. Who can attack?
  3. Where can they enter?
  4. What can go wrong in each flow?

It is a design exercise before coding.


2) Use case vs abuse case

  1. Use case: how normal users should use a feature.
  2. Abuse case: how attackers could misuse the same feature.

If you design only use cases, attackers will find the missing side.


3) Trust boundary

A trust boundary is where data moves from less trusted to more trusted zones.

Example:

  1. Internet user input -> backend API.
  2. Backend API -> internal admin service.

At each boundary, you must validate, authorize, and constrain actions.


4) Defense in depth

Never depend on one control only.

Example for transfer endpoint:

  1. Auth check
  2. Authorization check
  3. Input/business-rule validation
  4. Rate limit
  5. Fraud detection
  6. Logging/alerting

If one control fails, others still reduce damage.


How to prevent insecure design (practical sequence)

  1. Define security requirements per feature before development.
  2. Do threat modeling for critical workflows (auth, payments, admin, data export).
  3. Write abuse cases next to user stories.
  4. Design compensating controls (rate limits, lockouts, step-up auth, confirmations).
  5. Use secure design patterns/reference architectures.
  6. Add architecture/security review gates before release.
  7. Test business logic, not just technical vulnerabilities.
  8. Revisit design after incidents and near-misses.

Detection (important reality)

Scanners alone cannot fully detect insecure design.

You need:

  1. Architecture review
  2. Threat modeling workshops
  3. Business logic penetration testing
  4. Red-team style workflow abuse tests

Quick junior checklist

  1. Can an attacker automate this flow cheaply?
  2. What happens if a user repeats requests fast?
  3. Can old tokens/sessions be reused?
  4. Can one user affect another user’s assets?
  5. Is there step-up auth for high-risk actions?
  6. If one control fails, what backup control exists?

Business impact

  1. Account takeover
  2. Fraud and financial loss
  3. Large-scale abuse by bots
  4. Hard-to-fix systemic risk (because architecture must change)