All articlesSecurity Research

How Attackers Find Vulnerabilities in Your Web App — Before You Do

May 6, 2026·12 min read·Nautillo Pro Security Team

Attackers don't approach your application the way your developers built it. They work systematically — mapping the surface, probing inputs, following authentication flows backwards, and looking for the gaps between what the UI shows and what the API actually allows. Understanding this process is the fastest way to understand where your application is actually exposed.

The attacker's starting point isn't your homepage

Most developers think about their application from the outside in — what a user sees, the happy path, the intended flows. Attackers think about it from the inside out — what does the application do with data, where does it trust user input, what backend operations are triggered by which requests.

The first thing an attacker does isn't click around your UI. It's map the technical surface: what subdomains exist, what API endpoints respond, what JavaScript files are loaded, what HTTP headers the server returns, what error messages look like. All of this happens before a single exploit attempt.

By the time an attacker sends their first malicious payload, they've already built a complete picture of your application's architecture — often more systematically than your own team has.

Phase 1: Reconnaissance — mapping what exists

Reconnaissance is passive and largely invisible to your application. The attacker is discovering the attack surface without sending anything unusual.

Subdomain enumeration

DNS brute-forcing, certificate transparency logs (crt.sh lists every SSL certificate ever issued for your domain), and passive DNS records reveal subdomains you may have forgotten — staging.yourdomain.com, api.yourdomain.com, admin.yourdomain.com, old.yourdomain.com. Each is a separate attack surface, often with weaker security than the main domain.

JavaScript analysis

Your bundled JavaScript contains your entire client-side routing table, API endpoint paths, parameter names, and sometimes internal comments. An attacker who reads your main bundle knows every endpoint your frontend calls, the expected request format, and which routes exist even if they're not linked from the UI.

HTTP header fingerprinting

Response headers reveal your tech stack: X-Powered-By: Express, Server: nginx/1.18.0, X-AspNet-Version. Known framework versions map to known CVEs. A server header showing an outdated nginx version tells an attacker exactly which vulnerabilities to probe.

Error page harvesting

Sending requests to non-existent endpoints, malformed parameters, and unexpected content types produces error responses. Verbose error pages (stack traces, SQL queries, file paths) give attackers your internal architecture. Even the format of a 404 page reveals which framework you're using.

Historical data

The Wayback Machine archives old versions of your application. Endpoints that existed six months ago and were removed may still be live on the server — just not linked from the current UI. Attackers check what your application used to look like.

Phase 2: Authentication mapping — finding the trust boundaries

After mapping the surface, attackers focus on authentication and authorization boundaries — not to break authentication directly, but to understand what's behind it and how the application differentiates between user roles.

# What an attacker reads from your login flow:

POST /api/auth/login → JWT token structure reveals payload fields

GET /api/user/me → shows what fields the user object contains

GET /api/admin/users → does this return 401, 403, or 200?

# 401 = not authenticated (endpoint exists, auth required)

# 403 = authenticated but not authorized (confirmed endpoint, IDOR target)

# 404 = endpoint doesn't exist (or is intentionally hidden)

The difference between a 401 and 403 response tells an attacker whether an endpoint exists and is protected by role — which makes it a confirmed target for privilege escalation testing. Many developers return 404 on unauthorized requests to hide the existence of admin endpoints; this is correct.

Phase 3: Input identification — finding every place the application trusts you

Every point where user-supplied data enters the application is a potential injection point. Attackers catalogue them systematically: URL path parameters, query strings, request body fields, HTTP headers, cookies, file upload content.

The most missed inputs are the ones that don't appear in the UI:

HTTP headers passed to backend services

X-Forwarded-For, X-Real-IP, X-User-ID — if your application trusts these for authorization or logging, they're injectable

Hidden form fields and disabled inputs

Client-side 'disabled' attributes are not enforced server-side. Attackers submit these fields directly via a modified request

JSON fields not rendered in the UI

A response might include fields the UI doesn't display — role, is_admin, internal_id. Sending these fields back in subsequent requests tests mass assignment vulnerabilities

File content processed server-side

The contents of an uploaded file — not just its name — are an input if the server parses them (CSV, PDF, XML, image EXIF data)

WebSocket messages

WebSocket message payloads follow the same injection rules as HTTP request bodies but are often tested less rigorously

Phase 4: Active probing — one input at a time

With a complete map of the surface and all input points catalogued, the attacker begins systematic probing. This is methodical, not random — each input is tested for the vulnerability classes most likely to exist given its context.

Input typeFirst probesWhy
Numeric ID in URL pathIncrement/decrement the valueIDOR — does another user's resource return?
Search / filter fieldSingle quote, then SQL keywordsSQL injection — does the query break or behave differently?
HTML rendered fieldScript tag, img onerrorXSS — does the payload execute?
URL parameterInternal IP, metadata endpointSSRF — does the server fetch it?
File uploadPHP shell, polyglot fileRCE — is the file executed server-side?
JWT tokenalg:none, weak secretAuth bypass — does a modified token work?
Redirect parameterExternal domainOpen redirect — does it follow?

Phase 5: Chaining — turning low-severity into critical

Individual findings are not always the goal. The most damaging real-world attacks chain multiple lower-severity issues into a critical impact path. This is where human attackers and automated tools diverge most sharply.

Information disclosure → IDOR

An error message reveals an internal user ID format (e.g., UUID v1 with a timestamp component). The attacker generates IDs for nearby timestamps and uses them to access other users' resources. Neither finding is critical alone — together they're a data breach.

CSRF + stored XSS → account takeover

A stored XSS in a user-generated field fires in the admin panel. The payload makes a CSRF-protected state-change request — but because the XSS executes in the admin's browser, the CSRF token is valid. The attacker escalates to admin without ever authenticating as one.

Open redirect + OAuth → token theft

An OAuth flow uses a redirect_uri parameter. An open redirect on the same domain passes redirect_uri validation (same origin). The OAuth token is sent to the attacker-controlled final destination. Session hijacking without any injection.

SSRF + metadata endpoint → cloud takeover

An SSRF in a URL preview feature reaches the AWS metadata endpoint. The IAM credentials returned have S3 write access. The attacker uploads a backdoor to a publicly readable bucket used to serve static assets. RCE path from a single SSRF.

How long does this take?

For a typical web application, an experienced attacker completes reconnaissance and identifies the highest-value targets in under an hour. Confirmed exploitation of an IDOR or injection vulnerability often takes minutes once the input is identified.

The asymmetry is significant: you build the application over months, with business logic, deadlines, and feature pressure competing with security. An attacker spends a few hours looking at it fresh, with no context about why things are built the way they are, looking only for the gaps.

The practical response to this asymmetry isn't to spend more time on security reviews — it's to run the same systematic process the attacker runs, continuously, on every deployment. Not because one pass will catch everything, but because each pass catches regressions before attackers do.

Run the attacker's process on your own application

Nautillo Pro systematically maps your application's attack surface, identifies every input vector, and probes each one with the same techniques attackers use — SQL injection, XSS, IDOR, SSRF, authentication bypass, and more. Every confirmed finding includes the exact HTTP request that proves it. Results in minutes.