Attack Surface of a Modern Web App

By Davy Rogers

Every entry point an attacker can poke at. Know what you're defending.

Attack surface = everything an attacker can reach. Bigger surface = more chances.

  • Every HTTP endpoint
  • Every client-side route
  • Every file upload handler
  • Every third-party integration
  • Every dependency in package.json
  • Every env var, secret, config value

The layers

Network edge

DNS subdomain takeover, TLS misconfiguration, CDN bypass to origin, WAF gaps.

HTTP layer

Routes (including forgotten debug endpoints), methods (GET-only responding to DELETE?), headers (Host injection, CORS), cookies (HttpOnly? Secure? SameSite?), params and body.

Auth and sessions

Login (brute-force, stuffing, timing), password reset (predictable tokens, enumeration), OAuth (redirect URI, state param, referrer leakage), sessions (fixation, expiry, storage).

APIs

REST endpoints, GraphQL (introspection, nested query abuse, per-field auth), gRPC/WebSocket (less battle-tested than REST), internal APIs that skip auth because "they're internal."

Client-side

Your JS bundle ships to the attacker's machine.

Source maps in prod (readable code), API keys in client code (public), DOM-based XSS, open redirects, insecure postMessage, tokens in localStorage (accessible to XSS).

Data storage

Database injection (SQL, NoSQL, ORM), public S3 buckets, insecure pre-signed URLs, unauthenticated Redis/Memcached, sensitive data in logs.

Third-party dependencies

npm/PyPI packages (code you didn't write but run with full trust), SaaS integrations (API keys, webhooks), external <script> tags (code execution in your origin).

Infrastructure and CI/CD

Container images with CVEs, secrets in env vars, PR injection attacks, overly broad IAM roles, exposed K8s dashboards.

Reducing attack surface

  • Remove what you don't need. Dead endpoints, unused dependencies, debug routes.
  • Restrict access. Not every endpoint needs to be public. Network segmentation, auth, authz.
  • Limit functionality. JSON-only endpoint? Reject everything else.
  • Monitor what remains. Inventory endpoints, dependencies, integrations.

Practical exercise

Pick a feature in your application. Draw its data flow from the user's browser to the database and back. For each hop, list:

  1. What protocol is used?
  2. Who can reach this component?
  3. What input does it accept?
  4. What could an attacker do at this point?

You will likely find at least one thing you had not considered. That is the point.

The takeaway

Modern web app attack surface spans: network edge, HTTP layer, auth system, APIs, client-side code, data stores, dependencies, infrastructure.

More surface = more to defend.

Map it. Shrink it. Watch what's left.

Want a professional to look at it?Get an AppSec Health Check.