Course → Module 4: Reliability, Security & System Resilience

Why Anti-Patterns Matter More Than Patterns

Security patterns tell you what to do. Security anti-patterns tell you what people actually do in practice, and why those things fail. The gap between the two is where breaches live. Most production security incidents are not caused by sophisticated zero-day exploits. They are caused by known mistakes that teams made under time pressure, then never went back to fix.

This session catalogs the most common security anti-patterns, maps them to the OWASP Top 10, and connects the underlying principle of least privilege back to the systems thinking concept of leverage points from Session 0.6.

Anti-Pattern 1: Secrets in Code

Database passwords, API keys, JWT signing secrets, cloud provider credentials. When they appear in source code, they end up in version control. Once in version control, they are in every developer's local clone, every CI/CD runner, every backup, and potentially every fork if the repo is public.

This is not a hypothetical risk. GitHub's secret scanning program detects millions of leaked credentials per year. Automated bots scrape public repositories and exploit found credentials within minutes of commit.

The fix: Secrets belong in a secrets manager (AWS Secrets Manager, HashiCorp Vault, or at minimum, environment variables injected at runtime). The application code references a secret name, not a secret value. Rotation happens in the secrets manager without code changes.

Anti-Pattern 2: Over-Privileged IAM

A developer needs to read from one S3 bucket. The fastest way to unblock them: attach AdministratorAccess. It works. The ticket closes. Six months later, nobody remembers why that service account has full admin rights to every AWS service.

Over-privileged IAM is the most common security debt in cloud environments. It accumulates gradually. Each permission grant solves an immediate problem. Nobody schedules time to review and reduce permissions after the feature ships.

The principle of least privilege is a leverage point. It changes the structure of what's possible, not just what's allowed.

In systems thinking terms (Session 0.6), a leverage point is a place in the system where a small change produces a large effect. Least privilege is exactly that. By restricting what each identity can do, you change the blast radius of every possible failure mode. A compromised service with read-only access to one bucket is a minor incident. The same service with admin access is a catastrophe.

The fix: Start with zero permissions. Add only what is needed, scoped to specific resources. Use IAM Access Analyzer to identify unused permissions. Schedule quarterly permission reviews.

Anti-Pattern 3: Missing Input Validation

Every piece of data that crosses a trust boundary, from a user, from an external API, from a message queue, must be validated before processing. Missing input validation is the root cause behind multiple OWASP Top 10 categories: injection, XSS, and SSRF.

SQL Injection: The Classic

SQL injection occurs when user input is concatenated directly into a SQL query string. The attacker provides input that changes the query's structure, not just its data.

flowchart TD A["User submits login form"] --> B["Application builds SQL query"] B --> C{"Input validated?"} C -->|"No: String concatenation"| D["Query: SELECT * FROM users
WHERE name = '' OR '1'='1' --'"] D --> E["Database executes
modified query"] E --> F["Returns ALL user records"] F --> G["Attacker gains
unauthorized access"] C -->|"Yes: Parameterized query"| H["Query: SELECT * FROM users
WHERE name = $1"] H --> I["Database treats input
as data, not code"] I --> J["Returns 0 records
(no matching user)"] style D fill:#3a2020,stroke:#c47a5a,color:#ede9e3 style G fill:#3a2020,stroke:#c47a5a,color:#ede9e3 style H fill:#1a2a1a,stroke:#6b8f71,color:#ede9e3 style J fill:#1a2a1a,stroke:#6b8f71,color:#ede9e3

The fix is parameterized queries (prepared statements). The database driver separates the query structure from the data. User input can never alter the query's logic because it is treated as a value, not as SQL code. Every modern database library supports this. There is no valid reason to concatenate user input into SQL strings.

Cross-Site Scripting (XSS)

XSS occurs when user-supplied data is rendered in a browser without encoding. The attacker injects a script tag (or event handler) that executes in other users' browsers. Stored XSS persists in the database and fires for every user who views the affected page. Reflected XSS arrives via a crafted URL.

The fix: Output encoding appropriate to the context (HTML encoding for HTML content, JavaScript encoding for script contexts, URL encoding for URLs). Content Security Policy (CSP) headers provide a second layer by restricting which scripts the browser will execute.

OWASP Top 10 (2021): Detection and Remediation

The OWASP Top 10 is the industry standard reference for web application security risks. The 2021 edition reflects data from over 500,000 applications.

Rank Category Detection Fix
A01 Broken Access Control Penetration testing, automated access control tests Deny by default, enforce server-side, disable directory listing
A02 Cryptographic Failures Code review, automated scanning for weak algorithms Use strong algorithms (AES-256, RSA-2048+), encrypt at rest and in transit
A03 Injection SAST/DAST tools, code review for string concatenation Parameterized queries, input validation, ORMs
A04 Insecure Design Threat modeling, architecture review Security by design, threat modeling in planning phase
A05 Security Misconfiguration Configuration audits, cloud security posture tools Hardened defaults, automated config scanning, remove unused features
A06 Vulnerable Components SCA tools (Snyk, Dependabot), CVE databases Dependency scanning in CI/CD, automated updates, remove unused dependencies
A07 Auth Failures Credential stuffing detection, failed login monitoring MFA, rate limiting, bcrypt/argon2 for passwords, session management
A08 Integrity Failures CI/CD pipeline audits, dependency verification Signed artifacts, verified CI/CD pipelines, integrity checks
A09 Logging Failures Log audit, incident response drills Centralized logging, alert on auth events, tamper-proof log storage
A10 SSRF DAST tools, URL validation testing Allowlist for outbound URLs, block internal IP ranges, validate URL schemes

Least Privilege as a System Structure

Most security discussions frame least privilege as a policy: "only grant the minimum permissions needed." This is correct but insufficient. The systems thinking perspective asks a deeper question: what structure makes over-granting permissions easy, and what structure makes it hard?

If your default IAM policy is permissive, every new service starts with too much access. Developers must actively work to reduce permissions. This is a reinforcing loop in the wrong direction: convenience drives more permissive defaults, which normalizes broad access, which makes it harder to justify restricting any single service.

If your default IAM policy is deny-all, every new service starts with zero access. Developers must explicitly request each permission. This is friction, but it is intentional friction. The system structure forces the right behavior. You do not rely on discipline. You rely on design.

This is the leverage point. Changing the default from "allow unless restricted" to "deny unless granted" does not change one permission. It changes every future permission decision. That is structural change, and it is far more durable than any policy document.

Further Reading

Assignment

You are given access to a codebase for a web application. Perform a security review targeting three specific anti-patterns.

  1. Secrets audit. Identify 3 places where secrets might be hardcoded. Where would you look? (Hint: configuration files, environment setup scripts, test fixtures, Docker Compose files, CI/CD pipeline definitions.)
  2. Permission audit. Find 3 places where permissions might be over-granted. Consider IAM roles, database user privileges, file system permissions, and API token scopes.
  3. Input validation audit. Find 3 places where user input crosses a trust boundary without validation. Consider form submissions, API parameters, URL path segments, and file uploads.
  4. For each finding, classify the OWASP Top 10 category it falls under and propose a specific fix.