JavaScript Vulnerability Scanner: Test the Code Your Browser Actually Runs

ScanTitan drives a real headless browser through your React, Angular, or Vue app, reaches the routes a plain HTML crawler treats as a blank page, tests the XHR, fetch, and GraphQL calls behind the interface, and flags vulnerable JavaScript libraries by version. Every finding carries evidence and a specific fix.

 
ScanTitan · JS app scan
Rendering...
Illustrative sample, not a live scan · app.example.com · framework: React 18 · 24 routes
CRITICAL
DOM-based XSS in /dashboard/search
Untrusted input reaches innerHTML sink at runtime
HIGH
Vulnerable library: lodash 4.17.11
Prototype pollution · matched to NIST NVD · fix 4.17.21
MEDIUM
JWT stored in localStorage
Readable by any injected script · move to httpOnly cookie

React alone powers more than half of production web apps (2024 State of JS survey)

To an HTML crawler, a single-page app looks like one blank <div id="root">

The APIs behind your front end are the real attack surface

A scanner that cannot run JavaScript reports clean on an app it never loaded

What a JavaScript vulnerability scanner checks

JavaScript vulnerability scanner, sometimes called a JS vulnerability scanner or a JavaScript security scanner, tests a running web application, not its source code. It loads the app in a browser, runs the JavaScript, and probes what the app exposes at runtime.

That covers three layers most tools treat separately. It renders the client-side app in a headless browser to reach views a static crawler sees as blank. It intercepts the XHRfetch, and GraphQL calls the front end makes, because those API requests carry the real data and real risk. And it fingerprints the JavaScript libraries the page loads, matching each version against the NIST NVD.

Findings are ranked by what is actually exploitable, and each verifiable one ships with the evidence behind it and a specific fix.

50%+
of production web apps run on React, per the 2024 State of JS survey, so JavaScript coverage is the mainstream web, not an edge case.
React, Angular, Vue
framework routing detected and resolved so coverage reaches every client-side route, not just the shell
 
NIST NVD
loaded JavaScript libraries fingerprinted by version and matched to known CVEs
 
XHR · fetch · GraphQL
API calls captured during the scan and tested where your data actually lives

Why traditional scanners miss most JavaScript vulnerabilities

People searching for a Drupal exploit scanner want one of two things: a tool that fires exploit code at a site, which is a penetration testing decision, or a scanner that knows which findings attackers are using now. ScanTitan does the second, deliberately not the first, using public sources you can verify.

50%+
of production web applications run on React alone, per the 2024 State of JS survey. A scanner that cannot execute JavaScript is blind to the mainstream web.

Older scanners were built for a server that returns finished HTML. A modern JavaScript app returns a near-empty shell, often a single <div id="root">, then builds every view, route, and API call in the browser. To a crawler that only parses server HTML and follows links, that app is one blank page. It finds no routes to test and no API calls to intercept, then reports a clean scan on an app it barely loaded. That false all-clear is the real danger, not a noisy report.

The server ships a shell; the content only exists after the JavaScript runs in a browser.

Framework routers build paths at runtime, so a link-following crawler never reaches them.

A clean report on an app the scanner never loaded hides risk behind apparent success.

How to check a JavaScript app for vulnerabilities

Six stages, from a live URL to a verified, closed finding. A browser-driven process, not a source upload.

 
Point at the app URL

A JavaScript vulnerability scanner tests the running app, so you give it your application URL, not a code repository.

Render the JavaScript

A headless browser executes the bundle so the DOM builds and client-side routes become reachable.

Crawl every state

An event-based spider clicks, submits, and navigates the way a user would, reaching each view the app renders.

Capture the API calls

Every XHR, fetch, and GraphQL request the browser fires is recorded, then tested at the endpoint.

Add a recorded login

A replayed sign-in reaches authenticated views, with an AI fallback for complex SPA logins.

Match libraries, then fix

Loaded libraries are matched to the NIST NVD; you review by exploitability, apply the fix, and rescan.

Headless render · sample output
Illustrative example React 18 · 24 routes
shell
Server response <div id="root"></div> · no static links
EMPTY
render
JavaScript executed DOM built, router resolved
OK
routes
24 client-side routes reached /dashboard, /settings, /billing…
24
api
17 XHR/fetch/GraphQL calls intercepted tested for BOLA, injection
17
Static crawler would stop at the empty shell ScanTitan reached 24

Sample outcome: A static crawler saw one blank page. ScanTitan rendered the React bundle, reached 24 routes, intercepted 17 API calls, and surfaced a DOM-based XSS the shell scan never touched.

Client-side code

DOM-based XSS, unsafe sinks, and routing bypass tested where the logic runs, in the browser.

The APIs behind it

Captured XHR, fetch, and GraphQL endpoints tested for BOLA, injection, and excessive data exposure.

Loaded libraries

Every JavaScript library fingerprinted by version and matched against the NIST NVD for known CVEs.

What each layer surfaces
DOM-based XSS
Client-side · innerHTML sink
CRIT
BOLA on /api/v1/users/{{id}}
API layer
HIGH
lodash 4.17.11 prototype pollution
Library · NIST NVD
CVE
Rank by exploitability

Findings ordered by real-world risk and reachability, not raw severity label alone.

Apply the specific fix

Each finding names the change: sanitize the sink, upgrade the library, move the token, guard the route server-side.

Rescan to confirm

Rescan the same app to prove the finding is closed, and keep the record for your auditor.

Close the loop
lodash 4.17.11
Before: prototype pollution CVE
OPEN
lodash 4.17.21
After: upgraded, no matching CVE
CLOSED

How ScanTitan scans React, Angular, and Vue apps

Framework routing is not uniform. A scanner that treats every app as generic JavaScript misses paths. ScanTitan detects the framework and resolves its routes accordingly.

 

React

React ships a bundle that renders the UI and routes through a client-side router such as React Router, with no server links to follow. ScanTitan executes the bundle, extracts routes from the router, and drives the app to each view, then tests the components that render user input where DOM-based XSS and unsafe dangerouslySetInnerHTML tend to live.

Angular

Angular compiles to a bundle with its own router and template system. ScanTitan renders it, resolves the route configuration, and navigates to lazily loaded modules a static crawler never requests. It tests Angular's binding surfaces for injection, checks token and session handling, and captures the HTTP calls Angular services make to the backend.

Vue.js

Vue renders reactively and routes through Vue Router, so content and paths exist only once the JavaScript runs. ScanTitan executes the Vue bundle, follows Vue Router paths, and interacts with components to trigger revealing states. It watches for unsafe v-html rendering, checks client-side route guards that can be bypassed, and intercepts the API calls components make.

Detecting vulnerable JavaScript libraries and Node dependencies

Loaded-library fingerprinting

Identifies the JavaScript libraries your page actually loads and their exact versions.

NIST NVD version match

Matches each version against known CVEs, the approach Retire.js made standard.

Node.js dependencies

Flags dependencies a lockfile has frozen at a vulnerable version for server-rendered JavaScript.

A scheduled upgrade

Names the library, vulnerable version, CVE, and fixed release, so the fix is a planned upgrade.

Library findings · sample
1 crit 2 high
lodash 4.17.11
prototype pollution
matched to NIST NVD · loaded on /dashboard
DETECT [email protected] upgrade to 4.17.21
jQuery 1.12.4
known XSS
matched to NIST NVD · loaded site-wide
DETECT [email protected] upgrade to a supported 3.x

Most JavaScript risk is inherited, not written. This is the job of a JavaScript library vulnerability scanner, and it applies to Node.js dependencies as much as to browser libraries. A single outdated package pulled from npm can carry a known CVE into an otherwise careful codebase.

 

JavaScript-specific vulnerabilities we detect

The Drupal attack surface, not just a core version number.

DOM-based XSS

Instruments the dangerous browser sinks where untrusted data reaches code execution at runtime, the flaws a non-rendering scanner cannot see.

Prototype pollution

Catches attacker-controlled properties that poison the JavaScript object chain and quietly change how the whole app behaves.

Unsafe rendering sinks

Flags dangerouslySetInnerHTML in React and v-html in Vue, which turn user input into live, executable markup.

Client-side routing bypass

Finds guarded routes that render sensitive views because the access check runs only in the browser, never on the server.

Insecure token storage

Surfaces JWTs and session tokens kept in localStorage, where any injected script can read and steal them.

Bundle secrets and source maps

Spots API keys and source maps left in shipped JavaScript bundles, which hand attackers credentials and a map of your code.

The real attack surface is the API your JavaScript calls

The front end is a thin client. The data lives behind it, in the REST and GraphQL endpoints the app calls over XHR and fetch. Testing the UI alone leaves the real target untouched. As ScanTitan drives your app, it records every API request the browser makes, then tests those endpoints for broken object-level authorization (BOLA), where changing an ID returns another user’s data, plus excessive data exposure and injection reachable through the API. For a complete picture of that layer, pair this scan with the API vulnerability scanner. A JavaScript scan that ignores the API is testing the doorway and skipping the vault.

Every call captured

XHR, fetch, and GraphQL requests recorded live during the crawl, not guessed from the UI.

BOLA and access control

Change an object ID and the scanner checks whether another user's data comes back.

Excessive data exposure

Flags endpoints that return more data than the interface ever shows the user.

Scanning JavaScript apps behind a login

Recorded login

You capture the sign-in sequence once, and the scanner replays it at the start of each scan to reach protected routes and API calls.

AI authentication fallback

SPA logins use token exchanges and multi-step flows that break simple replay. An AI-assisted fallback adapts to the login instead of failing on it.

Where the risk lives

Most sensitive functionality sits behind the sign-in screen. A scan that only reaches public pages tests the least important part of your app.

Replayed every scan

The session is re-established on each run, so scheduled and repeat scans keep reaching authenticated views without manual steps.

SAST vs DAST vs SCA for JavaScript, and where source-code scanning fits

Searches for a JavaScript code vulnerability scanner or scanning js files on GitHub usually want static analysis, a different job from what ScanTitan does. Being clear about this saves you buying the wrong tool.

 
Approach What it reads Catches ScanTitan
SAST Source code, not running Insecure code patterns, hardcoded secrets in source Not offered; use a dedicated SAST tool
SCA Dependencies and lockfiles Known CVEs in libraries you import Covered at runtime via loaded-library fingerprinting
DAST The running app and its APIs XSS, injection, access control, real exposure Core capability, browser-driven
Honest scope. ScanTitan is DAST-first and adds loaded-library CVE detection. It does not read source files or scan a repository, and it will not pretend to. For code-level review, run a SAST tool alongside it. The two are complementary, and honest scope beats an inflated claim.

JavaScript scanner vs the full website vulnerability scanner

This page covers the JavaScript and single-page application side of scanning in depth. It is one capability of a broader platform. To test everything you expose, not only the JavaScript layer, start with the full website vulnerability scanner, which covers server-side flaws, injection, misconfigurations, and the JavaScript coverage described here in one scan. Use this page to understand how ScanTitan handles React, Angular, and Vue specifically, then run the website scanner for full coverage. If a scan uncovers signs of an active compromise rather than a latent flaw, website malware removal handles the cleanup.

 
This page · the deep dive

How React, Angular, and Vue apps, their libraries, and their APIs get scanned.

The hub · the whole picture

Server-side flaws, injection, misconfigurations, and this JavaScript coverage in one scan.

Common questions about JavaScript vulnerability scanning

Answered by our security team, not by a chatbot.

Only a scanner that runs a real browser can. Traditional scanners parse the HTML a server returns and follow static links, but a single-page application sends a near-empty shell and builds every view in the browser with JavaScript. A scanner that cannot execute that JavaScript sees a blank page and misses most of the app. ScanTitan drives a headless browser through your React, Angular, or Vue app, renders the client-side content, follows the framework's routes, and tests the API calls behind the interface. If a tool cannot execute JavaScript, it has no business reporting a JavaScript app as clean, because it never truly loaded it.

Traditional scanners read server-rendered HTML and follow the links inside it. A modern JavaScript app returns a shell, often a single empty div, then uses JavaScript to build the interface, handle navigation, and call APIs at runtime. A crawler that never executes that JavaScript finds no links to follow, no routes to test, and no API calls to intercept, so it reports a clean scan on an app it barely loaded. That false all-clear is worse than a noisy report, because it hides risk behind apparent success. Reaching a JavaScript app requires a scanner that renders and interacts with it like a browser.

ScanTitan renders the application in a headless browser so the framework's JavaScript executes, then extracts routes from the framework router and the JavaScript bundle to reach each view. It interacts with the app the way a user would, clicking and submitting to trigger states, and captures every XHR, fetch, and GraphQL request the app fires. Those API calls are tested alongside the client-side code for injection, access-control, and DOM-based flaws. Framework routing differs between React, Angular, and Vue, so ScanTitan resolves each one specifically rather than treating the app as generic JavaScript. The result is coverage of the whole app, not just its entry page.

Yes. ScanTitan fingerprints the JavaScript libraries your page loads, identifies each version, and matches it against the NIST National Vulnerability Database for known CVEs, the approach the Retire.js project made standard. A dated jQuery build can carry known XSS flaws, and an old version of lodash can carry a prototype pollution weakness, so version matching turns a hidden supply-chain risk into a clear upgrade. For Node.js front ends and server-rendered JavaScript, the same matching flags dependencies a lockfile has frozen at a vulnerable version. Each finding names the library, the affected version, the CVE, and the fixed release so remediation is a scheduled upgrade rather than a hunt.

They answer different questions, so the honest answer is both, used together. Static Application Security Testing (SAST) reads your source code without running it and is good at flaws visible in the code. Dynamic Application Security Testing (DAST), which ScanTitan runs, tests the deployed application and its APIs the way an attacker would, with no access to source, and catches issues that only appear at runtime such as DOM-based XSS and broken access control. SAST sees code a DAST scan cannot; DAST sees behavior a SAST scan cannot. ScanTitan is DAST-first and adds loaded-library CVE detection. For source-code review, pair it with a dedicated SAST tool.

Yes. ScanTitan supports authenticated scanning through a recorded login: you capture the sign-in sequence once, and the scanner replays it at the start of each scan to reach protected routes and API calls. Single-page application logins can be complex, using token exchanges and multi-step flows that break a simple form replay, so ScanTitan applies an AI-assisted authentication fallback that adapts to the login instead of failing on it. Authenticated coverage matters because most of an application's sensitive functionality sits behind the sign-in screen. A scan that only reaches public pages tests the least important part of your app.

The API is the real attack surface, so it should always be tested, and a JavaScript scan reaches part of it. As ScanTitan drives your app, it records the XHR, fetch, and GraphQL calls the browser makes and tests those endpoints for flaws such as broken object-level authorization and excessive data exposure. For endpoints the UI does not exercise, or for full coverage of a documented API, pair this scan with a dedicated API vulnerability scanner that tests documented and discovered endpoints in depth. Testing the JavaScript front end without testing its API leaves the layer that holds your data only partly checked.

Is ScanTitan's JavaScript vulnerability scanner right for you?

See what a real browser reaches in your app that a static crawler misses.

ScanTitan renders your React, Angular, or Vue application, tests the APIs behind it, flags vulnerable JavaScript libraries, and ranks findings by what is actually exploitable, each with a specific fix. Enter your app URL to get a report, or see how pricing works for your stack.

CISSP · GXPN · GCIH · GWAPT · CISA · CEH · ISO 27001 Lead Auditor ·· Author profile →