// HackTricks · Web Pentesting

Web Vulnerabilities Methodology

Web Vulnerabilities Methodology

Every web pentest has both obvious and hidden attack surfaces. This page is a checklist for confirming that the major vulnerability classes and application components have been reviewed.

Proxies

[!TIP] Modern web applications commonly use intermediary proxies, which may introduce exploitable parsing, caching, or routing behavior. These chains usually require both a proxy weakness and a compatible backend behavior.

User input

[!TIP] Most of the web applications will allow users to input some data that will be processed later.
Depending on the structure of the data the server is expecting some vulnerabilities may or may not apply.

Reflected Values

If the introduced data may somehow be reflected in the response, the page might be vulnerable to several issues.

Some of these vulnerabilities require special conditions, while others only require reflection in a dangerous context. The following page contains polyglots for quickly testing several classes:

Pocs And Polygloths Cheatsheet

Modern client-side code execution pivots

When a reflection bug lands in a modern SPA, spend a few extra minutes on the browser-managed primitives and native bridges the page already owns:

  • Service workers: inspect the active registration path, effective scope, and any Service-Worker-Allowed broadening. A low-impact HTML injection or DOM clobbering bug can become origin-wide persistence if the page registers a worker or feeds attacker-controlled values into importScripts().[3]
  • WASM / Emscripten modules: fuzz length, offset, and type conversions crossing the JS ↔ WASM boundary. In practice, a memory bug in linear memory may let you overwrite trusted HTML templates or state objects and upgrade a constrained client-side bug into DOM XSS.
  • Generated clients: minified bundles frequently disclose GraphQL persisted-query hashes, gRPC-Web method paths, postMessage handlers, WebSocket event names, and hidden admin routes even when the UI never exposes them.

For deeper exploitation ideas, check Abusing Service Workers, WebAssembly linear memory corruption to DOM XSS, and Code Review Tooling.

File System Access API: browser-native file read/write abuse

Chromium-family browsers expose showOpenFilePicker(), showSaveFilePicker(), and showDirectoryPicker() to trusted pages in a secure context and after a user gesture.[6][7] If a target web app, phishing lure, or malicious dependency can convince the user to approve a directory with read-write access, the page can operate on the selected files without dropping a native payload.[5]

Practical abuse patterns:

  • Enumerate the selected directory with for await (const [name, handle] of dirHandle.entries()) or values(), recurse into subdirectories, and filter by extension/MIME.
  • Read file contents with handle.getFile() and text(), arrayBuffer(), or stream(), then exfiltrate through fetch, XHR, or sendBeacon.
  • Overwrite files with createWritable() after a queryPermission() / requestPermission({mode: 'readwrite'}) flow. This is the primitive that enables browser-native ransomware or destructive tampering.[5][9]
  • Check IndexedDB for serialized FileSystemFileHandle / FileSystemDirectoryHandle objects because legitimate apps often persist handles and later reuse them after queryPermission() / requestPermission() checks.
  • Review the UX around picker prompts: fake AI upscalers, editors, and media tools can plausibly ask for an input file first and an output folder second, making the write warning look legitimate.[5]

Important boundaries:

  • This is not arbitrary disk access. Chromium blocks or constrains many sensitive locations, but user-chosen media folders can still be high-value targets. In recent public research, Pictures, Videos, and Android DCIM roots were practical lure targets.[5]
  • A normal web page still cannot become native malware: global keylogging, arbitrary desktop screenshots, and OS persistence remain outside the browser sandbox unless another vulnerability is present. The real primitive is user-approved local file read/write.
  • Browser support is concentrated in Chromium. Chrome shipped the API on desktop in Chrome 86 and extended it to Android/WebView in Chrome 132; Firefox and Safari do not expose the same picker methods.[8]

Search functionalities

If the functionality may be used to search some kind of data inside the backend, maybe you can (ab)use it to search arbitrary data.

Forms, WebSockets and PostMsgs

When a WebSocket sends messages or a form lets users perform actions, request-forgery and message-trust vulnerabilities may arise.

Cross-site WebSocket hijacking & localhost abuse

WebSocket upgrades automatically forward cookies and do not block ws://127.0.0.1, so any web origin can drive desktop IPC endpoints that skip Origin validation. When you spot a launcher exposing a JSON-RPC-like API through a local agent:[1]

  • Observe emitted frames to clone the type/name/args tuples required by each method.
  • Bruteforce the listening port directly from the browser (Chromium will handle ~16k failed upgrades) until a loopback socket answers with the protocol banner—Firefox tends to crash quickly under the same load.
  • Chain a create → privileged action pair: e.g., invoke a create* method that returns a GUID and immediately call the corresponding *Launch* method with attacker-controlled payloads.

If you can pass arbitrary JVM flags (such as AdditionalJavaArguments), force an error with -XX:MaxMetaspaceSize=<tiny> and attach -XX:OnOutOfMemoryError="<cmd>" to run OS commands without touching application logic. See WebSocket attacks for a walk-through.

Installers / setup wizards / recovery leftovers

First-run installers and recovery endpoints are often forgotten in production. If a live application still exposes paths such as /install/, /setup/, /init/, /admin/install, /setup/setupadministrator.action, or readable config files such as /config/database.php, treat them as high-value takeover primitives instead of low-value information leaks.[2]

Checks to perform:

  • Fuzz for installer and reconfiguration paths with ffuf, dirsearch, or wordlists containing install, setup, wizard, init, upgrade, db, config, and admin.
  • Open the wizard and determine whether it still accepts database / SMTP / admin parameters after deployment, or whether a server-side setupComplete / lock file can be flipped or bypassed.
  • If the installer accepts arbitrary DB settings, test whether the application will connect to an attacker-controlled external DB and bootstrap its schema there. This can yield admin creation, backend state disclosure, or application DoS if the remote DB later disappears.
  • After any successful reinitialization, revisit old authenticated tabs and test whether pre-existing sessions remain valid even after the backend DB/configuration is restored. PHP apps often keep session state outside MySQL, so restoring the DB may not revoke attacker sessions.
  • Review incident-response paths: password reset, admin creation, DB restore, installer rerun, maintenance exit. If none of them rotate session IDs or invalidate server-side session stores, keep testing for persistent dashboard access.

Operational notes:

  • Outbound connectivity matters: if the web tier can reach arbitrary MySQL hosts, SSRF-style egress restrictions are missing and installer abuse becomes much easier.
  • Sudden 500 errors immediately after setup changes can indicate the application is still pointing to attacker-supplied infrastructure.
  • Framework/app-specific examples exist (for example Confluence setup reactivation admin creation), but the reusable technique is production reinstallation / reinitialization abuse.

HTTP Headers

Depending on the HTTP headers given by the web server some vulnerabilities might be present.

Bypasses

There are several specific functionalities where some workarounds might be useful to bypass them

Structured objects / Specific functionalities

Some functionalities will require the data to be structured in a very specific format (like a language serialized object or XML). Therefore, it’s easier to identify if the application might be vulnerable as it needs to be processing that kind of data.
Some specific functionalities may be also vulnerable if a specific format of the input is used (like Email Header Injections).

Files

Functionalities that allow uploading files might be vulnerable to several issues.
Functionalities that generate files including user input might execute unexpected code.
Users that open files uploaded by users or automatically generated including user input might be compromised.

External Identity Management

Passkeys / WebAuthn handoffs

Passkeys are origin-bound, so the usual bug is not “steal the secret” but abuse the workflow around the ceremony:[4]

  • Try registration/login confusion: start a WebAuthn ceremony in one account or browser, then complete it from another session and check whether the signed challenge is still bound to the correct user, RP, and browser state.
  • Treat QR, device-code, wallet, and cross-device approvals exactly like password-reset tokens: check replay, stale approvals, session swapping, and whether a completed ceremony authenticates a browser different from the one that initiated it.
  • If you already have XSS or strong clickjacking on the relying-party origin, test whether you can drive extension/browser UI to approve a legitimate passkey login for the victim without exposing the credential material.

See Account Takeover and Clickjacking for concrete attack patterns.

Other Helpful Vulnerabilities

These vulnerabilities might help to exploit other vulnerabilities.

Web Servers & Middleware

Misconfigurations in the edge stack often unlock more impactful bugs in the application layer.

Application Frameworks & Stacks

Framework-specific primitives frequently expose gadgets, dangerous defaults, or framework-owned endpoints.

[!TIP] Always download the front-end bundles and *.map files before assuming a route or action is unreachable. Modern builds often leak Next.js Server Actions, GraphQL persisted-query hashes, tRPC router names, gRPC-Web paths, feature flags, and role strings that are perfect for low-privilege replay and authorization testing.

Quick grep targets inside downloaded bundles:

rg -n 'sourceMappingURL|createServerReference|Next-Action|queryHash|persistedQuery|grpc-web|protobuf|new WebSocket\(|postMessage\(' ./static ./dist ./_next ./assets 2>/dev/null

Useful follow-up reading: Code Review Tooling and Next.js.

CMS, SaaS & Managed Platforms

High-surface products often ship with known exploits, weak plugins, or privileged admin endpoints.

APIs, Buckets & Integrations

Server-side helpers and third-party integrations can expose file parsing or storage-layer weaknesses.

Supply Chain & Identifier Abuse

Attacks that target build pipelines or predictable identifiers can become the initial foothold before exploiting traditional bugs.

Web3, Extensions & Tooling

Modern applications extend into browsers, wallets, and automation pipelines—keep these vectors in scope.

References