Software Securityhome
Fix a findingSearch
Guides

Application security

Secure design, implementation, testing, and response throughout the software lifecycle.

67 guides · 21 labs · 12 local projects · 3 learning paths

Start here

Secure coding

Keep untrusted input out of queries, markup, commands and parsers, and fail safely.

16 guides
Recipe

Fix SQL injection in Python sqlite3

Bind query values separately from SQL syntax, then prove the fix preserves legitimate behavior and blocks an injection probe.

Guide

Prevent XSS at the output boundary

Choose text rendering, context-aware encoding, or deliberate HTML sanitization according to how the browser will interpret the value.

Guide

Handle failures without leaking internals or weakening controls

Give callers a useful, bounded response while preserving protected diagnostic evidence and safe application state.

Guide

Ship without debug modes, verbose errors or exposed files

Turn off debug output, publish an allowlisted build and probe each deployment for exposed files and endpoints.

Guide

Keep untrusted values out of executable syntax

Choose a safe interface for each interpreter and bound the work performed by parsers and converters.

Guide

Run external programs without command or argument injection

Run programs from an argument list with no shell, end options before user values, and keep untrusted arguments away from Windows batch files.

Guide

Keep untrusted input out of eval, expression languages and templates

Keep code and templates constant, pass input as data, and treat in-process sandboxes as one layer, not a boundary.

Guide

Preserve framework security controls across the request lifecycle

Trace middleware, persistence and rendering so custom code does not bypass the protections supplied by the framework.

Guide

Parse bounded JSON and XML into an explicit application schema

Separate parser capabilities from schema rules, reject ambiguous and coercible inputs, and implement the boundary in a complete Python project.

Guide

Keep untrusted object keys out of prototype and authority paths

Trace an actual nested-merge mutation, replace it with a narrow schema, and make authorization independent of inherited properties.

Guide

Prevent CRLF header injection, log forging and CSV formula injection

Carriage return and line feed separate HTTP header fields, log records and CSV rows, and a leading = turns a spreadsheet cell into a formula. Let the framework write headers, log structured JSON, and neutralize formula triggers in exports.

Guide

Prevent NoSQL, LDAP, XPath and expression-language injection

SQL is not the only query language that receives user input. Stop MongoDB operator injection with type checks and $eq, escape LDAP filter values, pass XPath values as variables, and never evaluate SpEL or OGNL built from request data.

Guide

Validate input safely and prevent regex denial of service

Find and fix exponential and quadratic regex backtracking with measured examples, choose linear-time engines or timeouts, and build allowlist validation that decodes once and rejects type confusion and parameter pollution.

Guide

Prevent file inclusion: LFI, RFI, dynamic imports and template names

Stop request data from choosing which file, module or template your application loads: local and remote file inclusion in PHP, dynamic require() and import() in Node.js, importlib and template names in Python, Thymeleaf view names in Spring, render in Rails, and the allowlist fix that works in all of them.

Guide

Create temporary files safely: mkstemp, O_EXCL and private directories

Stop symlink, hardlink and pre-created-file attacks on the temporary files your code writes in shared directories such as /tmp: create each file atomically with O_EXCL and owner-only permissions through mkstemp or its equivalent in shell, Python, Java, Node.js, Go, .NET and Rust, keep related files in a private directory, and treat the Linux protected_* sysctls and systemd PrivateTmp as a backstop.

Case study

Case study: Spring4Shell (CVE-2022-22965)

How Spring's data binding let request parameters reach the class loader on JDK 9 and later in 2022, why the denylist workaround leaked, and what it teaches about framework-level mass assignment.

Languages and memory safety

Find and contain memory-safety bugs in C and C++, and audit unsafe Rust and FFI.

2 guides

Access control

Check every object, function and field against the caller, not the request.

3 guides

Browser security

Request forgery, cross-origin access, content security policy and rich text.

5 guides

Secure features

Uploads, archives, webhooks, outbound fetches and concurrent operations.

10 guides
Guide

Design a safer file-upload pipeline

Treat upload receipt, content processing, storage, and later delivery as separate security decisions.

Guide

Verify webhook deliveries before acting

Verify the provider’s signature over the correct bytes, then apply replay, authorization, and idempotency controls before a business action.

Guide

Constrain server-side fetches to their intended destinations

Prevent untrusted URLs from turning a preview, import, or webhook feature into access to internal services.

Guide

Preserve business invariants under concurrent requests

Make a balance, reservation or approval rule hold when requests overlap, retry and fail halfway through.

Guide

Extract archives without escaping the destination

Prevent traversal, link tricks, overwrites and decompression exhaustion while preserving legitimate file extraction.

Guide

Convert untrusted office documents and PDFs in an isolated parser

DOCX, XLSX and ODF files are ZIP archives of XML, and PDFs can carry scripts; the converters that read them are large C and C++ programs with a long CVE history. Check the package before any parser reads it, convert each document in a container with no network, no writable root and hard limits, kill it at a deadline, and re-render to pixels when people will open the result.

Guide

Secure WebRTC signaling, TURN relays and media servers

WebRTC encrypts media, but signaling decides whose keys you trust and TURN relays wherever it is allowed. Authorize every signaling message, mint short-lived TURN credentials, deny internal addresses and harden media servers.

Guide

Prevent business-logic flaws with server-side invariants

Recompute prices on the server, run workflows as state machines, build reset links from configuration, limit valuable flows, and turn each business rule into an invariant that the database and the tests both check.

Guide

Redirect users only to destinations you control

Check every redirect target taken from a request, so attackers cannot borrow your domain for phishing, carry OAuth tokens off-site or steer a server-side fetcher through your redirects.

Guide

Consume third-party APIs safely (OWASP API10:2023)

Treat every upstream and third-party API response as untrusted input: validate it against a schema, set connect and read timeouts, cap the response size, refuse to follow redirects blindly, keep TLS verification on, and scope the credentials you hold for each provider.

Design and code review

Find trust-boundary failures before they ship: threat models and change review.

9 guides
Guide

Review tenant boundaries before implementation

Trace tenant identity through requests, data stores, caches, jobs, and administration, then turn plausible isolation failures into tests.

Guide

Review a code change through its trust boundaries

Turn a pull request into a small set of security claims that can be checked against the surrounding system and tests.

Guide

Choose a threat modeling method and turn its findings into tests

Use the four-question frame to scope a design, pick STRIDE, attack trees, LINDDUN or PASTA by the question you need answered, and leave behind threat records and abuse-case tests the team can run.

Guide

Write testable security requirements and a security Definition of Done

Derive security requirements from OWASP ASVS 5.0, abuse cases and the threat model, write them as acceptance criteria a test can fail, trace each one to a test or evidence, and close stories against a short security Definition of Done.

Reference

Abuse case library: tests and controls by feature

Recurring abuse cases for sign-up and login, password reset, MFA enrolment, invites, file upload, payments and coupons, webhooks, search, export, admin and AI chat or agents: the attacker goal, preconditions, a concrete test and the control, each linked to CWE and CAPEC.

Reference

Threat pattern library for threat modeling

Thirty-two recurring threat patterns grouped by identity, authorization, parsers, concurrency, integrations, data exposure, supply chain, availability and AI agents, each with where it shows up on a data-flow diagram, mitigations, a verification step and STRIDE, CWE and CAPEC links, plus a YAML catalog and a script that lists patterns per diagram element.

Reference

Secure design patterns: a catalogue for insecure-design (A06)

A catalogue of reusable secure-design patterns, grouped by concern, each with when to use it, a short example and the failure it prevents: choke-point authorization, capability tokens, parse-don't-validate, safe-by-default APIs, tenant scoping, fail-closed, idempotency, and more.

Guide

Worked threat model: a mobile banking app

A complete worked threat model for a mobile banking-style app: the data-flow diagram and its elements, STRIDE threats on the client, the transport and the backend, and the mitigations mapped to OWASP MASVS v2 controls and current Android and iOS platform APIs.

Guide

Worked threat model: an LLM agent with tools

A complete worked threat model for an LLM agent with tools: the data-flow diagram, the threats from prompt injection, excessive agency, data exfiltration, confused-deputy and memory poisoning, and the mitigations, mapped to the OWASP Top 10 for LLM Applications 2026 and the OWASP Top 10 for Agentic Applications 2026.

Security testing

Static and dynamic analysis around a verified finding, and parser fuzzing.

4 guides

Mobile, desktop, embedded and smart contracts

Platform storage and permissions, privileged bridges, firmware updates and smart-contract invariants.

9 guides
Guide

Review trust boundaries in mobile and native clients

Protect local data and platform interactions while keeping server-side authorization independent of the client’s behavior.

Guide

Review mobile storage, links and platform permissions

Keep local artifacts and platform entry points from exposing authority that belongs on the server.

Guide

Constrain desktop IPC and privileged helpers

Keep renderer content, local callers and plugins from turning a narrow feature into unrestricted operating-system access.

Guide

Design firmware updates that can recover safely

Connect trusted boot, update authorization, rollback policy and end-of-life behavior to the device’s actual failure modes.

Guide

Test smart contracts through state invariants

Define the properties funds and privileges must preserve, then exercise callbacks, transaction sequences and exceptional conditions locally.

Guide

Harden an Android app's storage, network and entry points

Encrypt local secrets with Android Keystore keys now that Jetpack Security is deprecated, set transport policy in Network Security Configuration, close exported components and mutable PendingIntents, confine WebViews, verify App Links and judge Play Integrity verdicts on the server, mapped to OWASP MASVS 2.1.

Guide

Harden an iOS app's storage, network and entry points

Store secrets in the Keychain with the narrowest accessibility class, set file protection explicitly, keep App Transport Security on, prefer universal links, constrain WKWebView bridges, keep step-up keys in the Secure Enclave, verify App Attest on the server and ship an accurate privacy manifest, mapped to OWASP MASVS 2.1.

Guide

DeFi attack patterns: oracles, flash loans, proxies and signatures

The four smart-contract attack classes beyond reentrancy: price-oracle manipulation, flash-loan amplification, upgradeable-proxy storage collisions and uninitialized implementations, and signature replay, each with vulnerable and fixed Solidity, Foundry tests and verified incidents.

Case study

Case study: CrowdStrike Channel File 291 (July 2024)

How a CrowdStrike content update crashed Windows hosts in July 2024: a field-count mismatch hidden by wildcard tests, a missing bounds check, and no staged rollout.

Vulnerability response

Respond to a vulnerable dependency and run a disclosure process.

9 guides
Guide

Respond to an exploited or malicious dependency

When a dependency vulnerability is being exploited, or a package version is malicious, triage gives way to incident response: find every running copy, contain it, patch and redeploy, hunt for exploitation, rotate secrets and close on deployed evidence.

Guide

Run coordinated vulnerability disclosure from report to advisory

Make private reporting discoverable, verify reports, coordinate a tested remedy, and give affected users enough information to act.

Case study

Case study: Log4Shell (CVE-2021-44228)

How a JNDI lookup in Apache Log4j became internet-wide remote code execution, why transitive and shaded dependencies made it so hard to patch, which mitigations held, and what it teaches about dependency inventory and SBOMs.

Guide

Start with a VDP, then add bug bounties and penetration tests

Publish a vulnerability disclosure policy and security.txt first, add a bug bounty only when you can triage and fix at the pace rewards bring, and buy penetration tests with a written scope, rules of engagement and a retest.

Case study

Case study: MOVEit Transfer mass exploitation (CVE-2023-34362)

How one unauthenticated SQL injection in an internet-facing file transfer product let the Cl0p group steal data from thousands of organizations in days in 2023, how defenders found the web shell, and the vendor and customer controls that would have limited it.

Guide

Set up a PSIRT: services, intake, triage, SLAs and the CNA role

How to structure and run a product security incident response team on the FIRST PSIRT Services Framework: organizational models, intake channels, triage, response targets, a case record and SLA script, becoming a CVE Numbering Authority under the CNA rules 4.2.0, and coordinating with other vendors.

Guide

Publish security advisories with CSAF, VEX, CVE records and OSV

What a useful security advisory contains and how to publish it in the formats tools read: a validated CSAF 2.0 VEX document, the CSAF provider files, CVE records through a CNA (CVE Record Format 5.2), and OSV records for open-source packages. Covers the status of CSAF 2.1 as of October 2026.

Guide

Respond to product security incidents: plan, tabletop and postmortem

An incident response plan for product security incidents (exploited vulnerabilities, compromised releases, leaked signing keys, malicious dependencies shipped to customers), aligned with NIST SP 800-61 Rev. 3, with reporting clocks, a two-scenario tabletop exercise template and a blameless postmortem template.

Case study

Case study: Citrix Bleed (CVE-2023-4966)

How a NetScaler memory over-read leaked session cookies that bypassed passwords and MFA in 2023, why patching did not end hijacked sessions, and how the pattern returned in 2025.

Lab · Foundation · 20–30 min

CSRF lab: Protect an account change from a forged request

An account settings handler trusts the session cookie even when another site causes the request. Repair the request policy and preserve legitimate settings updates.

Lab · Practitioner · 25–40 min

Path traversal lab: Keep archive entries inside their extraction directory

An import job writes archive entry names directly beneath its work directory. An entry containing ../ can escape. Repair the entry-name policy before any file is created.

Lab · Practitioner · 25–40 min

Race condition lab: Repair a balance check that races

Two simultaneous purchases both see the same balance and spend more credit than the account owns. Replace the read-then-write sequence with the supplied atomic debit.

Lab · Foundation · 20–30 min

IDOR lab: Repair an invoice authorization bug

Bob can retrieve Alice’s invoice by changing the URL. You own the endpoint’s permission check. Reproduce the leak, patch the function below, and prove that Alice can still read her invoice.

Lab · Advanced · 30–45 min

Webhook signature and replay lab: Repair a webhook handler that pays twice

Your handler rejects some genuine deliveries and records replayed payments twice. Fix the function below, then test valid, changed, replayed, and concurrent deliveries.

Lab · Advanced · 30–45 min

SSRF lab: Guard an outbound fetch against SSRF

A webhook sender fetches whatever URL the user gives it, and follows redirects. An attacker can point it at the cloud metadata service or an internal admin page, directly or through a redirect. Repair the guard so it resolves each host and refuses private addresses, in literals, encodings and redirects alike.

Lab · Foundation · 20–30 min

CORS policy lab: Grant CORS to the right origins only

An API reflects whatever Origin a request carries and allows credentials, so any website can read a signed-in user’s data from it. Repair the CORS policy so it grants access only to the configured origins and keeps caches correct.

Lab · Practitioner · 25–40 min

CSP builder lab: Build a strict Content-Security-Policy

A page sends a Content-Security-Policy whose script-src allows any HTTPS origin, so an injected external script runs despite the nonce. Repair the builder so it produces a strict nonce-based policy from the document’s declared needs.

Lab · Practitioner · 25–40 min

HTML sanitization lab: Configure a sanitizer for user comments

A comment feature keeps the formatting users submit, but its sanitizer configuration re-enables event handlers, unknown URL schemes and extra tags, so a comment can run script. Repair the configuration so only a small set of formatting tags and safe links survive.

Lab · Practitioner · 25–40 min

Business logic lab: Price an order without trusting the client

A checkout trusts the price and quantity each cart line sends, adds every coupon code it recognizes, and never limits redemptions. Customers can choose their price, order negative quantities and stack discounts. Repair the pricing function so every amount comes from server data and every coupon rule holds.

Lab · Foundation · 20–30 min

SQL injection lab: Separate SQL structure from data with sqlite3

A product search builds its SQL by formatting the shopping category and search term straight into the query string, so a crafted term can read other tables or return every row. Repair it to use sqlite3 parameters, while keeping the legitimate search working.

Lab · Practitioner · 25–40 min

Path traversal lab: Serve an uploaded file without path traversal

A download endpoint joins the requested name onto the upload directory and opens it, so ../ or an absolute path reads files anywhere on disk, and a symlink in the directory points outside it. Repair it to resolve the final path and refuse anything outside the upload directory.

Lab · Practitioner · 25–40 min

SSRF validation lab: Validate a fetch URL with ipaddress

An image importer fetches any URL a user submits, so a crafted URL reaches the cloud metadata service or an internal host, directly or through an encoded IP literal. Repair the validator so it parses the URL, resolves the host and allows only public addresses.

Lab · Foundation · 20–30 min

Open redirect lab: Return users to this site only

After sign-in, the login page redirects to whatever its next parameter says, so a link to your own domain can end on a look-alike site. Return users only to a page on this site.

Lab · Practitioner · 25–40 min

File upload lab: Accept avatars without publishing pages

A profile-picture upload trusts the client’s Content-Type and file name, stores files in the public folder and serves them with the client’s type, so an SVG with a script runs in the site’s origin. Repair the upload decision.

Lab · Practitioner · 25–40 min

OS command injection lab: Run git without a shell

A repository browser pastes request values into a git command line for the shell, so a semicolon starts a second command and a leading dash becomes a git option. Run git directly, with each value as one argument.

Lab · Foundation · 20–30 min

Mass assignment lab: Update only the fields users may edit

PATCH /me merges the whole request body into the stored user, so adding "role": "admin" turns a member into an administrator. Change only the fields a user may edit on their own profile.

Lab · Practitioner · 25–40 min

Buffer over-read lab: Stop a heartbeat over-read

A model of C memory: a TLS heartbeat handler echoes as many bytes as the request claims, not as many as arrived, so a short request returns the next client’s cookie, as Heartbleed did. Add the bounds checks.

Lab · Practitioner · 25–40 min

SSTI lab: Render a welcome banner without template injection

A welcome banner is built by concatenating the user’s display name into a Jinja template string, so a crafted name is evaluated as a template: it runs expressions, bypasses autoescaping and reads the render context. Repair render_welcome so the name is data, not template source.

Lab · Practitioner · 25–40 min

XXE lab: Parse an uploaded invoice without resolving external entities

An invoice importer parses uploaded XML with a parser that resolves external entities, so a crafted DOCTYPE reads a local file into the response (XXE). Repair parse_invoice so the parser never resolves external entities, loads no DTD and makes no network request.

Lab · Practitioner · 25–40 min

Pickle deserialization lab: Load a session token without pickle

A session loader parses JSON but falls back to pickle for “legacy” tokens, so a crafted pickle runs code when it is loaded. Repair load_token to parse JSON only and validate it against a fixed schema, and leave no path that unpickles untrusted bytes.

Local project · Node.js 22+ · npm

Secure a real HTTP API

Run Express requests with real signed tokens. Repair invoice authorization and stop user-controlled properties from changing roles or tenants.

Local project · Python 3.11+ · standard library

Make a checkout transaction atomic

Reproduce two competing withdrawals against SQLite, then repair the transaction so funds cannot be spent twice.

Local project · Python 3.11+ · standard library

Keep extracted files inside their boundary

Inspect actual ZIP entries and repair a path policy. Test traversal, links, duplicate entries, expansion limits and ordinary nested files.

Local project · Python 3.13+ · Expat 2.6.0+ · standard library

Parse bounded JSON and XML invoices safely

Repair a real JSON/XML parser boundary: reject duplicate fields, coercion, unknown schema, DTDs and oversized documents while keeping valid invoices usable.

Local project · Clang + Python 3.11+

Repair a native parser using sanitizer evidence

Compile a C parser with AddressSanitizer, observe a real out-of-bounds access, and repair allocation, length and output-capacity checks against boundary tests and 80 generated frames.

Local project · Node.js 22+ · no dependencies

Stop prototype pollution at merge and authorization boundaries

Observe real prototype mutation from nested JSON merges, then repair schema selection, own-property authorization and arbitrary-key dictionaries without breaking valid updates.

Local project · Node.js 22+ · no dependencies · GitHub Actions and GitLab CI YAML

Repair a security pipeline for GitHub Actions and GitLab CI

Repair two pipelines that run gitleaks, Semgrep, OSV-Scanner, Trivy and cosign but cannot fail and trust pull requests, until every action is pinned to a commit SHA, every image to a digest, gates block and only the main branch signs the pushed digest.

Local project · Swift 6 · Xcode 16+ · iOS Simulator

Keep an iOS app's storage, links and web bridge in bounds

Repair a SwiftUI banking app until its XCTest suite passes in the iOS Simulator: Keychain storage, App Transport Security in the built Info.plist, link handling and a WKWebView bridge.

Local project · Kotlin · Android Gradle Plugin 9.4 · Robolectric 4.17 · Docker

Repair an Android app's links, components, network policy and storage

Repair a Kotlin banking app until its Robolectric tests and Android Lint pass in a pinned SDK container: links and intent redirection, exported screens, network security configuration and Keystore-encrypted storage.

Local project · Node.js 22.12+ · npm · Electron 44

Stop untrusted pages from using an Electron bridge

Run a real Electron notes app whose preload passes any IPC channel through and whose main process trusts every sender. Repair the sandbox, the contextBridge API, the sender and payload checks, navigation and window rules, the CSP and permissions until a link, a foreign page or injected script can no longer write files or launch programs.

Local project · Node.js 22+ · no dependencies

Recover from failed firmware updates with A/B slots

Repair the update client and bootloader of a simulated dual-slot device: Ed25519-signed manifests, a monotonic anti-rollback floor, writes to the inactive slot, trial boots with automatic fallback and authenticated recovery. The tests inject bad signatures, signed rollbacks, power loss at every flash write and images that never confirm, and write an evidence file of each failure and the boot that followed.

Local project · Python 3.11+ offline · Docker for the live tests

Convert untrusted documents in a locked-down container

Repair a document worker that drives LibreOffice and Ghostscript in Docker, until a zip bomb and DTD payloads stop at preflight, the container has no network or writable root, and a hung conversion is killed with its container.

Tool · Runs in your browser

CSP evaluator

Check a Content Security Policy for unsafe-inline, unsafe-eval, wildcards and broad schemes, missing object-src, base-uri and frame-ancestors, and weak reporting.

Tool · Runs in your browser

Security headers analyzer

Check pasted response headers: HSTS, CSP, X-Content-Type-Options, framing, Referrer-Policy, Permissions-Policy, COOP, COEP, CORP, caching and Set-Cookie attributes.

Tool · Runs in your browser

ReDoS checker

Find nested quantifiers, ambiguous alternatives, adjacent overlapping repeats and unanchored leading repeats in a regex, and time it against generated attack strings.

Tool · Runs in your browser

security.txt validator

Validate a security.txt file against RFC 9116 and the IANA field registry: Contact, Expires, Preferred-Languages, https URIs, Canonical, CSAF and the OpenPGP signature wrapper.

Find your next answer

Type to search. Search runs in your browser.

Searches run in your browser, but the host can infer them from the index files they load. The address shows your search so you can bookmark or share it.