← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Security by Design

Security OWASP A5:2021 PHP 5.0+ Intermediate
debt(d9/e9/b9/t7)
d9 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9). detection_hints.automated is 'no' — absence of threat modelling or security-by-design thinking cannot be detected by any tool; it manifests only when vulnerabilities surface in production or audit.

e9 Effort Remediation debt — work required to fix once spotted

Closest to 'architectural rework' (e9). quick_fix suggests threat modelling before writing code, but retrofitting security-by-design into an existing system means restructuring trust boundaries and data flows — common_mistakes explicitly notes 'architectural flaws cannot be patched'.

b9 Burden Structural debt — long-term weight of choosing wrong

Closest to 'defines the system's shape' (b9). applies_to covers web/api/cli — this is an SDLC-level principle (per tags: principles, architecture, sdlc) that shapes every architectural decision; absence or presence defines the entire system's security posture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception is explicit: developers believe security by design means 'adding security features' (checks, libraries) when it actually means making insecure states structurally impossible — this contradicts the intuitive reading of the name.

About DEBT scoring →

Also Known As

secure by design security-first design shift-left security

TL;DR

Integrating security requirements into software architecture and design from the very beginning, rather than bolting it on afterwards.

Explanation

Security by Design (SbD) means security is a first-class requirement alongside functionality — considered during threat modelling, system architecture, data flow design, and API contracts, not discovered during a pre-release penetration test. Core principles include: minimise attack surface, apply least privilege at every layer, use defence in depth, fail securely (default-deny), avoid security through obscurity, keep design simple (complexity breeds vulnerabilities), and separate duties. For PHP projects this means: choosing framework defaults that are secure out of the box, designing data flows that never touch user input without sanitisation, and reviewing every new feature through a threat-model lens.

Common Misconception

Security by design means adding security features to an application. It means designing the system so insecure states are structurally impossible — e.g. an API that cannot return another user's data by construction, not by a check that could be forgotten.

Why It Matters

Security by design builds security into architecture decisions from the start — it is far cheaper to design out a vulnerability than to patch it after deployment, and some flaws cannot be patched without restructuring.

Common Mistakes

  • Security as a final phase ('we'll add security later') — architectural flaws cannot be patched.
  • Designing for the happy path only — not considering what happens when inputs are malicious.
  • No threat modelling in the design phase — security gaps are discovered in production.
  • Prioritising features over security constraints in early sprints — security debt compounds quickly.

Code Examples

✗ Vulnerable
// Design that makes security impossible to add later:
class UserController {
    // All user data in one object — cannot restrict field visibility per role
    // No audit log hook points — cannot add logging without rewriting
    // Direct DB calls everywhere — cannot add encryption layer without touching all code
    // Feature shipped — security 'added later' means full rewrite
}
✓ Fixed
// Security by design — bake it in from the start

// 1. Default deny
class Policy {
    public function can(User $user, string $action, mixed $resource): bool {
        return false; // deny by default — explicitly grant per action
    }
}

// 2. Fail securely — errors don't open access
function getUser(int $id): User {
    return User::findOrFail($id); // throws, not returns null
}

// 3. Immutable value objects — can't enter invalid state
readonly class Email {
    public function __construct(public string $value) {
        if (!filter_var($value, FILTER_VALIDATE_EMAIL))
            throw new \InvalidArgumentException("Invalid email: $value");
    }
}

// 4. Least privilege — each component gets minimum permissions it needs

Added 15 Mar 2026
Edited 22 Mar 2026
Views 72
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 2 pings T 6 pings F 3 pings S 4 pings S 5 pings M 3 pings T 0 pings W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 22 Amazonbot 10 Perplexity 5 SEMrush 5 Ahrefs 4 Google 4 Unknown AI 2 Bing 2 ChatGPT 1 Claude 1 Meta AI 1 Sogou 1 PetalBot 1
crawler 57 crawler_json 2
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: High
⚡ Quick Fix
Run a threat model before writing code: identify trust boundaries, entry points, sensitive data, and the top 3 most likely attack scenarios
📦 Applies To
PHP 5.0+ web api cli
🔗 Prerequisites
🔍 Detection Hints
Absence of threat model documentation security requirements or security review in development process
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File


✓ schema.org compliant