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.
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.
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.
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.
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.
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 --><!-- served from https://app.example -->
<script src="https://cdn.other.net/lib/v1.4.2/v.js"
integrity="sha384-AbC…"
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.other.net/lib/v1.4.2/a.css"
integrity="sha384-XyZ…" crossorigin="anonymous">
<!-- Pin a versioned URL: a hash on a "latest" URL breaks when the file changes.
Or self-host the file and the scanner treats it as first-party. -->Reference: what the code does
| Item | Value | Where it comes from |
|---|---|---|
| Input | the 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 means | absolute 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 / cap | one finding per resource URL; scripts are listed first; at most 20 findings in total | seen, _MAX_FINDINGS |
| Finding | category MISSING_SRI, source DAST_URL, confidence 0.9, method GET, endpoint = page URL | _build_finding |
| Network | none | module docstring |
| Scan depth | runs at both quick and deep | factory.py DAST list |
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.