Lesson 13 / 25
Insecure Design
Flaws no amount of perfect code fixes.
Business logic and abuse cases
Insecure design means missing or ineffective security controls in the design: password reset codes that can be guessed without rate limits, a checkout that trusts a client-supplied price, unlimited free-trial sign-ups, or workflows that skip a verification step. Prevent it with threat modelling, abuse cases ("how would a fraudster use this?"), secure design patterns, rate limits and quotas, server-side recalculation of prices and totals, and security requirements reviewed alongside features.
Secure by design, hardened by default
Some flaws are in the design itself; others come from insecure defaults and configuration.
Recomputing totals on the server
Python sketch for a checkout endpoint.
# VULNERABLE DESIGN: trusts the price sent by the browser
total = sum(item["price"] * item["qty"] for item in request.json["items"])
# SECURE DESIGN: prices come from the catalogue; quantities are validated
total = 0
for item in request.json["items"]:
product = catalogue.get(item["product_id"]) or abort(400)
qty = int(item["qty"])
if not 1 <= qty <= 20:
abort(400)
total += product.price * qtyWrite abuse cases next to user stories
"As an attacker, I want to reuse a discount code 1,000 times" leads directly to the needed control.
Quick check: Which is an insecure design flaw rather than a coding bug?
- A typo in a variable name
- No rate limit on guessing six-digit password reset codes
- A missing semicolon
- A slow database index
Answer
No rate limit on guessing six-digit password reset codes — The control is missing from the design.