Back to Blog
Jan 20, 20264 min readOnuzulike Anthony

STRIDE Threat Modeling for Web APIs

A structured approach to thinking about what can go wrong — before it does. Walking through STRIDE on a realistic streaming API.

SecuritySecurityArchitectureAPI

Threat modeling sounds like an enterprise process with whiteboards and consultants. It doesn't have to be. STRIDE is a checklist — six threat categories you run through for each component or flow in your system. The output is a list of threats and mitigations, not a 40-page report.

STRIDE stands for: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege.

Let's walk through a concrete example: a streaming API that issues encrypted stream tokens and proxies video embeds. This maps directly to what NodWatch's streaming pipeline does.

The System

Client → POST /api/stream/token (auth required)
       → GET  /api/stream/proxy?token=... (validates + proxies embed)

The token encodes: embed URL, user ID, expiry (60 seconds), and the stream server selection.

S — Spoofing

Can an attacker impersonate a legitimate user or service?

Threat: An attacker replays a stolen stream token to access content without authentication.

Mitigation: Token expiry (60 seconds) limits the window. The token encodes the userId — the proxy route validates that the requesting session matches. Use AES-GCM encryption for tokens (not just base64) so the contents can't be modified or inspected.

Threat: An attacker spoofs the Origin header to bypass CORS restrictions on the token endpoint.

Mitigation: The token endpoint requires a valid authenticated session, not just an origin check. CORS is defense-in-depth; auth is the real gate.

T — Tampering

Can an attacker modify data in transit or at rest?

Threat: An attacker modifies the token query parameter to change the embed URL to one that serves malicious content in the iframe.

Mitigation: The token is AES-GCM encrypted with an authenticated tag. Any modification to the ciphertext renders the MAC invalid and the decryption fails. The embed URL is never taken from the URL — only from the decrypted, verified token.

Threat: The embed URL itself could be manipulated if the stream provider is compromised.

Mitigation: The frame-src CSP header only allows the five known stream provider domains. An injected URL from an unknown domain is blocked by the browser.

R — Repudiation

Can an attacker deny having performed an action?

Threat: A user disputes charges or accesses, claiming they never streamed certain content.

Mitigation: Log token issuance with user ID, timestamp, content ID, and IP. Log every proxy request with the same data. The token itself is signed with the user ID — it cannot be forged by another user.

I — Information Disclosure

Can an attacker access data they shouldn't?

Threat: The embed URL (which may contain partner API keys as query parameters) is exposed in client-side JavaScript or network logs.

Mitigation: The proxy route decrypts the token server-side and makes the outbound request from the server — the actual embed URL is never sent to the browser. The client only ever sees the proxy URL.

Threat: Error responses from the stream provider reveal internal implementation details.

Mitigation: The proxy catches all errors and returns a generic 503 to the client. Provider errors are logged server-side only.

D — Denial of Service

Can an attacker degrade or disable the service?

Threat: An attacker hammers POST /api/stream/token to exhaust server resources or trigger provider rate limits.

Mitigation: Rate limit token issuance per user (10/minute). The 60-second token expiry means tokens can't be stockpiled. Auth requirement means unauthenticated DoS is harder.

Threat: Large numbers of proxy connections exhaust connection pool capacity.

Mitigation: The proxy is deployed on Cloudflare Workers (auto-scaling). Timeouts on the outbound fetch prevent hanging connections.

E — Elevation of Privilege

Can an attacker gain capabilities beyond what they're authorized for?

Threat: A free-tier user obtains a stream token intended for premium content.

Mitigation: The token issuance endpoint checks the user's subscription tier before issuing a token for premium content. The token doesn't carry the tier — the check is at issuance time.

Threat: An attacker exploits a vulnerability in the token encryption to forge tokens without authentication.

Mitigation: Use crypto.subtle.importKey with AES-GCM-256. The 256-bit key is stored as a Cloudflare secret — not in source code or .env.


Running STRIDE takes 30–60 minutes for a well-defined flow. Do it for every new endpoint that handles auth, payments, or content gating. The output — a table of threats and mitigations — becomes the security section of your design doc.