DAST scanner · passive

Subresource Integrity

A script loaded from someone else's CDN runs with the full power of your page. An integrity="sha384-…" attribute lets the browser refuse bytes that do not match a hash you pinned. isitsecure reads the HTML it already captured and reports every cross-origin script or stylesheet that has no such attribute. It sends no requests of its own.

DASTMediumLowSupply chainSnapshot-based

What it reads and what it reports

The scanner takes the page HTML from the snapshot and walks every <script src> tag, then every <link> tag whose rel contains stylesheet. A tag is reported only when its URL points at another host and the tag carries no integrity attribute. A script is graded higher than a stylesheet.

page: https://app.example verdict <script src="https://cdn.other.net/v.js">other host, no integrity MEDIUM · External script missing SRIreported once per URL <link rel="stylesheet" href="https://f.other.net/a.css">other host, rel=stylesheet, no integrity LOW · External stylesheet missing SRICSS can restyle a form, not run code <script src="https://cdn.other.net/v.js" integrity="sha384-…">other host, integrity present quiet · integrity attribute foundany non-empty value counts <script src="/static/app.js">no scheme or host: first-party path quiet · first-partyyou control the origin <script src="https://app.example/main.js">absolute URL, same host as the page quiet · same host as the pagecompared after dropping a leading www.

1The snapshot holds the rendered HTML of https://app.example. The scanner reads it as text. No request is sent, and an empty page returns no findings.

2A <script src> with an absolute URL on another host and no integrity in the tag is the main finding. Script → MEDIUM, because the CDN's bytes run as your page.

3A <link> counts only when its rel contains stylesheet. The same test on its href gives stylesheet → LOW.

4If the tag carries integrity="…" with any non-empty value, the scanner moves on. It checks that the attribute exists, not that the hash is right.

5First-party resources are excluded. A relative path has no host, and an absolute URL on the page's own host is first-party. Both are skipped, because SRI matters most for code you do not control.

Built from the code, not a markdown doc

This scanner has no page under docs/scanners/. Everything here is taken from isitsecure/engine/scanners/sri_scanner.py and the README scanner-table row ("External CDN scripts/styles loaded without Subresource Integrity hashes"). The regexes, severities, the first-party test and the cap of 20 findings are read directly from that file.

What the hash buys you

An integrity attribute is a promise made at build time: these exact bytes, and no others. The browser downloads the resource, hashes it, and compares. Without the promise the browser has nothing to compare against and runs whatever the CDN returns.

Your page <script src="https://cdn.x.net/v.js" integrity="sha384-AbC…" crossorigin="anonymous"> (no integrity attribute)> the hash was computed at build time GET /v.js CDN (third party) not your server, not your control v.js bytes: original v.js bytes: altered compromised: payload appended v.js + payload Browser sha384(received bytes) = Zq9… integrity attribute = AbC… hashes differ → resource blocked, the script never runs the page keeps working without the injected code integrity attribute = (absent) nothing to compare against payload executes with full page privileges this is the exact state the scanner reports

1The page loads v.js from a CDN it does not run. With SRI, the tag also carries a SHA-384 hash of the file as it looked when the developer reviewed it.

2The CDN is breached, or its account is taken over. v.js now contains attacker code. Every site that links it is affected at once.

3The browser downloads the altered file, hashes it, and compares it with the attribute. The hashes differ, so the resource is blocked.

4Take the attribute away and the browser has no reference value. The altered script runs with the page's DOM, cookies and tokens. This is the state the scanner flags.

Why it matters

The finding text states the risk directly: if the CDN is compromised, "the browser will execute the altered content with full page privileges". A stylesheet is graded lower because it cannot run code, though it can still restyle a login form. The fix the finding gives is to add an SRI hash (integrity="sha384-...") and a crossorigin attribute.

Vulnerable vs fixed markup

The same two tags, before and after. The hash is the base64 SHA-384 digest of the exact file you reviewed; crossorigin lets the browser read the cross-origin response so it can hash it.

<!-- served from https://app.example -->
<script src="https://cdn.other.net/lib/v1.4.2/v.js"></script>      <!-- MEDIUM -->
<link rel="stylesheet" href="https://cdn.other.net/lib/v1.4.2/a.css"> <!-- LOW -->

Reference: what the code does

ItemValueWhere it comes from
Inputthe snapshot's rendered HTML only (not the JavaScript files)snapshot.html_content
Script rule<script … src="…"> with a quoted src, cross-origin, no integrity= in the tag → MEDIUM_SCRIPT_TAG_RE, _scan_scripts
Stylesheet rule<link> with rel containing stylesheet, a quoted href, cross-origin, no integrity → LOW_LINK_TAG_RE, _scan_stylesheets
External meansabsolute URL with scheme and host, and a host different from the page's (a leading www. is ignored)_is_external, is_first_party_url
Dedup / capone finding per resource URL; scripts are listed first; at most 20 findings in totalseen, _MAX_FINDINGS
Findingcategory MISSING_SRI, source DAST_URL, confidence 0.9, method GET, endpoint = page URL_build_finding
Networknonemodule docstring
Scan depthruns at both quick and deepfactory.py DAST list
Things it does not do

It does not verify that an integrity value is a valid or correct hash, and it does not check for crossorigin. A subdomain of your own site (for example cdn.app.example) has a different host and is reported as external. A protocol-relative URL such as //cdn.other.net/v.js has no scheme, so the first-party test passes and the tag is skipped. Unquoted src values and resources added to the DOM by JavaScript after load are not matched by the regexes.