Unit 2: Reading and checking files · Lesson 6 of 6 · 20 min
Case file: a script you do not control
A single third-party script tag gave a stranger code on every page. Find yours and pin it.
mission
- You are
- You are the analyst reviewing what the shop's pages load.
- Situation
- The integrity check failed on index.html. The change added a script tag that loads code from another company's server on every visit.
- Goal
- Find every external script, check whether it is pinned, and produce the pin for the local one.
- Hand in
- A short list: script, host, pinned or not, and the fix.
case file
Polyfill.io Domain Takeover
polyfill.io (websites embedding it) · 2024
In February 2024 the polyfill.io domain and GitHub account were acquired by a company named Funnull, prompting warnings from the original author and from Cloudflare. In June 2024 Sansec reported that the service was injecting malicious code into more than 100,000 websites that loaded the script, redirecting some mobile users to scam/betting sites. The registrar later put the domain on hold, and CDN providers offered mirrors.
What went wrong
Websites loaded executable JavaScript from a third-party domain at runtime, so a change of domain ownership gave the new owner code execution in every visitor's browser.
What would have stopped it
- Self-host third-party scripts or pin them with Subresource Integrity hashes rather than loading mutable scripts from external domains.
- Use a Content Security Policy that limits allowed script sources, and review it when dependencies change.
- Monitor ownership and reputation changes for external domains your site depends on, and remove dependencies no longer needed.
What defenders could have seen
- Client-side script monitoring flagging changed content from a third-party script URL.
- CSP violation reports or user reports of unexpected redirects on mobile.
- Threat intel alerts on domain ownership changes for embedded script hosts.
Find every script tag
grep -rn '<script' --include=*.html .
./index.html:3:<head><meta charset="utf-8"><title>Example Shop</title><script src="https://cdn.example-metrics.net/m.js"></script></head>
you should see One tag, in index.html, loading from cdn.example-metrics.net.
Pull out the hosts
Every external host in a src attribute can change what your visitors run.
grep -rhoE 'src="https://[^/"]+' --include=*.html . | sort | uniq -c
1 src="https://cdn.example-metrics.net
you should see One external host.
Is it pinned?
Subresource Integrity puts a hash in the tag. The browser refuses the file if the hash does not match.
grep -c 'integrity=' index.html
0
you should see 0. Nothing stops that host from sending different code tomorrow.
Make a pin for your own script
SRI hashes are SHA-384 in base64. This is the value for the shop's own app.js.
openssl dgst -sha384 -binary assets/js/app.js | openssl base64 -A; echo
4h81cTvsL1O461b2sCPOA/JJdd19AAj2A5mN7gYbXe1sZ1kOiO7BQCN6PglNxJ/p
you should see A 64-character base64 string. It goes in the tag as integrity="sha384-...".
defender tip SRI only works for files that never change. For a script that a vendor updates daily, host a reviewed copy yourself instead.
The same script, two ways
<script src="https://cdn.example-metrics.net/m.js">
The owner of that domain decides what runs
<script src="/assets/js/m.js" integrity="sha384-..." crossorigin="anonymous">
A copy you reviewed, refused if it changes
What a defender takes away
- 1Every external script is code you run but do not control.
- 2Pin with SRI or host a reviewed copy.
- 3Domains change hands; your page keeps trusting them.
Questions
0 of 3 solved
Answer each one from what you find on your lab machine.