Applied capstone
By the end of this module you will be able to:
- Apply STRIDE and attack tree analysis to a real system architecture
- Identify OWASP Top 10 and API Security Top 10 issues in a described codebase
- Recommend identity and access control improvements for a given context
- Propose a logging and detection plan with specific event types and Sigma rule patterns
Scenario: FinPay API architecture
FinPay's current architecture: Node.js API deployed on AWS EC2 behind an Application Load Balancer; PostgreSQL on Amazon RDS containing customer PII, payment card tokens, and transaction records; API keys issued per merchant, passed as a query string parameter; React single-page application served from S3 via CloudFront; manual deployments via SSH directly to EC2 with no CI/CD pipeline; application logs written to the EC2 instance's local disk, not forwarded to any central store.
The six researcher findings are: (1) API key visible in browser network tab and server logs via URL query parameter; (2) merchant_id in a transaction query can be changed to retrieve another merchant's history; (3) full card tokens returned in all transaction responses even when not needed; (4) SQL injection via search filter returning a database error with a partial SQL query; (5) refund endpoint accepting any refund_amount with no server-side maximum, tested with 10,000x the original transaction amount; (6) API accepts plain HTTP connections on port 80.
Part 1: STRIDE classification and OWASP mapping
Applying STRIDE and the OWASP Top 10:2025 and the API Security Top 10 (2023) to each finding:
- Finding 1 (API key in URL): STRIDE: Information Disclosure (the credential is exposed in logs and history). OWASP: A07:2025 Authentication Failures. Mitigation: move the key to the Authorization request header; rotate the exposed keys immediately.
- Finding 2 (merchant_id enumeration): STRIDE: Elevation of Privilege (accessing resources beyond authorisation scope). OWASP: A01:2025 Broken Access Control and API1:2023 BOLA. Mitigation: server-side check that the authenticated merchant's ID matches the requested merchant_id before returning data.
- Finding 3 (card tokens in all responses): STRIDE: Information Disclosure. OWASP: API3:2023 Broken Object Property Level Authorisation. Mitigation: define explicit response schemas per endpoint; return card tokens only when the caller explicitly needs them and has the required scope.
- Finding 4 (SQL injection): STRIDE: Tampering (data integrity compromised) and Information Disclosure. OWASP: A05:2025 Injection. Mitigation: parameterised queries or prepared statements for all database interactions.
- Finding 5 (unlimited refund amount): STRIDE: Tampering (financial integrity). OWASP: API4:2023 Unrestricted Resource Consumption (business logic abuse variant). Mitigation: server-side maximum validation that the refund amount does not exceed the original transaction amount.
- Finding 6 (plain HTTP accepted): STRIDE: Information Disclosure (card tokens and API keys transmitted in cleartext). OWASP: A04:2025 Cryptographic Failures. PCI DSS: Requirement 4.2.1 (TLS required for cardholder data in transit). Mitigation: redirect all HTTP to HTTPS at the load balancer; enforce TLS 1.2 minimum.
Part 2: Identity and verification remediation
API authentication weaknesses (Finding 1): (a) Query string transmission exposes the key in server logs, browser history, and referrer headers. Fix: transmit in the Authorization header. (b) One key grants all operations with no scope restriction. Fix: scope keys per operation type (read, write, refund), using OAuth 2.0 Client Credentials flow with named scopes per RFC 6749 Section 4.4. (c) For a financial API processing four million pounds daily, a static API key is a weak authentication method. Fix: migrate server-to-server integrations to OAuth 2.0 Client Credentials with short-lived access tokens, or to mTLS for the highest-assurance integrations.
Merchant portal (React SPA): The portal should use Authorization Code with PKCE (RFC 7636) for user-delegated access. The Implicit flow is deprecated in RFC 9700 because access tokens appear in URL fragments accessible to browser history and referrer headers.
Which logins need phishing-resistant credentials: not every FinPay login carries the same risk, so the second-factor tier should follow the blast radius of the account. Interactive human logins split into three groups. The engineers who deploy code and hold direct database access, and any internal operator who can authorise a refund, sit at the top: a stolen session there moves money or rewrites production, so these accounts need phishing-resistant credentials, meaning FIDO2 security keys or passkeys that are bound to the real origin and cannot be relayed through an adversary-in-the-middle proxy. Ordinary one-time codes and push prompts do not clear this bar, because a convincing proxy page harvests the code and replays it in real time. Merchant portal accounts that can issue refunds belong in the same tier for the same reason. Read-only merchant logins are lower risk and can start on an authenticator app, though passkeys are the better default everywhere. The machine-to-machine API path is not an MFA question at all: it has no human to prompt, so its answer is the scoped OAuth client credentials or mTLS described above, not a second factor.
Minimum-viable DevSecOps pipeline: At pull request: Semgrep with an injection ruleset blocks SQL concatenation patterns before merge. At dependency update: Snyk or Dependabot alerts on critical CVEs in package.json. At build: SBOM generation (cdxgen or Syft) produces a CycloneDX SBOM stored alongside the artefact. Before deployment to staging: OWASP ZAP active scan against the staging environment, failing on any HIGH finding. At release: SAST quality gate enforcement.
Part 3: Logging and detection plan
Current logging (console.log to local disk) does not capture: (1) authorisation failures per object (each instance of Finding 2 exploitation leaves no trace); (2) SQL error events with query context (Finding 4 generates database errors not forwarded to any central store); (3) refund amount anomalies (Finding 5 leaves no structured record).
Minimum log events for the FinPay scenario: (1) authentication.success and authentication.failure with source_ip, merchant_id, and timestamp; (2) api.access events including authenticated_merchant_id, resource_owner_id (the merchant_id in the request), endpoint, and response_status; (3) data.export events for card token returns including requesting_merchant_id and record_count; (4) database.error events with a sanitised error code (not the raw SQL error).
Detection rule for Finding 2 (BOLA enumeration): Sigma condition that counts distinct resource_owner_id values grouped by authenticated_merchant_id over a five-minute timeframe; alert if the count exceeds ten. This would have detected the T-Mobile-style enumeration within minutes rather than weeks.
PCI DSS compliance gaps: Finding 4 (SQL injection in a system containing cardholder data) directly violates Requirement 6.2.4 (protection against injection attacks). Finding 6 (plain HTTP) violates Requirement 4.2.1 (TLS for cardholder data in transit). Evidence required at audit: proof of parameterised queries in the codebase, SAST results showing no injection findings, and load balancer configuration showing HTTP redirect to HTTPS.
In the FinPay scenario, which detection most directly catches Finding 2, the broken object level authorisation enumeration?
Common misconception
“A single insecure design flaw can be categorised under only one OWASP category.”
Finding 2 in the FinPay scenario maps to both A01:2025 Broken Access Control and API1:2023 BOLA simultaneously. Finding 4 (SQL injection in a system containing card data) maps to A05:2025 Injection, A09:2025 Security Logging and Alerting Failures (the error is not logged), and directly violates PCI DSS Requirement 6.2.4. Real security findings typically fail multiple controls across multiple frameworks at once.
Common misconception
“A penetration test that finds no critical vulnerabilities proves the application is secure.”
A penetration test is a point-in-time assessment. It reflects the security posture at the moment of testing against a specific scope with specific testers using specific techniques in a defined timeframe. Applications change continuously: new code deployed the day after a pentest may introduce a CVSS 10.0 vulnerability. A more useful framing is that a clean pentest provides confidence in the security of the tested scope at the tested point in time. Continuous security through automated SAST/DAST in the CI/CD pipeline, combined with annual pentests, provides significantly higher assurance than annual pentests alone.
Core distinctions
- A single insecure API design can simultaneously fail across multiple OWASP categories: the FinPay scenario exhibits BOLA, injection, excessive data exposure, missing business logic validation, and cryptographic failures simultaneously.
- Identity controls, verification pipelines, and logging are interdependent: without structured logs you cannot detect BOLA exploitation; without a CI/CD pipeline you cannot gate on injection vulnerabilities; without strong authentication there is nothing for access control to verify against.
- The shift from manual deployment to an automated gated pipeline is one of the highest-use security improvements for an early-stage engineering team. A pull-request SAST gate would have caught Finding 4 before it ever reached production.
- PCI DSS and security best practice usually align: fixing the FinPay security issues would simultaneously address the PCI DSS Requirement 4.2.1 (TLS) and Requirement 6.2.4 (injection protection) compliance gaps.
You have completed the Applied stage. You can threat model, secure identity flows, harden web applications and APIs, gate releases, and detect incidents. The Practice and Strategy stage scales these skills to organisational programmes: secure SDLC, zero trust architecture, cloud security, supply chain risk, and incident response at enterprise scale. The first module is Secure software development lifecycle.
Standards and sources cited in this module
Web application vulnerability classification covering A01:2025 to A10:2025 referenced in the FinPay analysis.
OWASP API Security Top 10 2023
API vulnerability classification covering BOLA, resource consumption, and property-level authorisation.
NIST SP 800-218: Secure Software Development Framework (SSDF)
Secure software development practices: produce well-secured software, respond to vulnerabilities.
Payment Card Industry Data Security Standard: Requirements 4.2.1 (TLS) and 6.2.4 (injection protection).