Dependency and supply-chain security
Limit the damage any npm package or third-party script can do if it is malicious, compromised, or buggy.

WHAT YOU WILL BE ABLE TO DO
Learning outcomes
- Explain dependency and supply-chain security in plain language.
- Connect the behavior to the underlying browser or framework model.
- Implement the core pattern and reason through edge cases.
- Answer common follow-ups without relying on memorized phrases.
01Explain it simply
Most of the code shipped to users isn't written in-house — it's npm packages and their transitive dependencies, plus any third-party scripts loaded at runtime. Supply-chain security is about limiting the damage any one of those can do.
One-line definition: Limit the damage any npm package or third-party script can do if it is malicious, compromised, or buggy.
02Mental model
Risk enters at install-time — a package or a postinstall script that runs on your build machine — and at run-time — a script executing in users' browsers with full page access. Defenses: a committed lockfile with integrity hashes pins exact versions; automated advisories catch known-vulnerable versions; Subresource Integrity makes the browser reject a CDN script whose content changed; and minimizing dependencies plus sandboxing third-party embeds in iframes shrinks the attack surface.
03Step by step
- Commit the lockfile and install with the frozen/CI flag so builds can't silently resolve new versions.
- Review new dependencies for necessity, maintenance, and transitive weight before adding them.
- Run automated vulnerability advisories in CI and triage real exploitable findings promptly.
- Add SRI hashes to any script or style loaded from a third-party origin.
- Load risky third-party widgets in a sandboxed iframe so they can't read the host page or its tokens.
- Restrict what scripts can connect to with CSP connect-src, limiting exfiltration if one is compromised.
04Working example
<script src="https://cdn.example.com/widget.js" integrity="sha384-BASE64HASH" crossorigin="anonymous"></script>The browser downloads widget.js, hashes it, and only executes it if the hash matches the integrity attribute. If the CDN is compromised and serves altered code, the hash no longer matches and the browser refuses to run it — turning a silent supply-chain compromise into a visibly blocked resource.
05Where it is used
- Limiting blast radius of a compromised npm package or its postinstall script
- Detecting and prioritizing known CVEs in the dependency tree
- Ensuring a third-party CDN can't silently swap in malicious script content
- Containing analytics, chat, and A/B widgets so they can't read auth tokens from the page
06Common mistakes
- Not committing or not enforcing the lockfile, so CI resolves versions the developer never tested
- Running npm audit but treating every finding as noise, missing the one that's actually exploitable in context
- Loading third-party scripts directly into the page instead of a sandboxed iframe, giving them full DOM and token access
- Assuming a popular package is safe — popularity is a bigger target, not a guarantee
07Interview answer
Separate install-time risk from run-time risk. Name concrete controls — lockfile plus integrity, SRI, advisories, iframe sandboxing — rather than just keep dependencies updated.
Why is loading a third-party analytics script with a plain script src tag riskier than embedding it in a sandboxed iframe?
A script tag runs in the page's own origin with full access to the DOM, cookies, localStorage, and any tokens present, so a compromise of that script compromises the whole page; a sandboxed iframe runs in a separate context that can't read the host page's DOM or storage.
DDConcept deep dives
Deep dive 1
Install-time and run-time risk are different threats with different controls
A dependency can attack at install-time — a package or postinstall script running on the build machine with access to environment variables, credentials, and the filesystem — or at run-time, where a third-party script runs in the user's browser inside your origin with full DOM, cookie, and storage access. Conflating them leads to gaps; each needs its own mitigations.
- Install-time controls: committed lockfile with integrity, frozen installs, script-execution policy, dependency review.
- Run-time controls: Subresource Integrity, sandboxed iframes for widgets, CSP script-src and connect-src.
- A postinstall script and a loaded <script> tag are both 'a dependency', but the containment strategy differs.
Deep dive 2
Pin what you tested, verify what you load
A committed lockfile with integrity hashes means every install reproduces the exact dependency tree that was reviewed and tested, and a tampered package fails verification. For code loaded at run-time from a CDN, Subresource Integrity does the equivalent: the browser hashes the file and refuses to execute it if the content changed, turning a silent CDN compromise into a visible blocked resource.
- Install with the frozen or CI flag so the lockfile is enforced, not just present.
- Add integrity attributes to every third-party script and stylesheet tag.
- A changed hash is a signal to investigate, not to update the hash and move on.
Deep dive 3
Every dependency is trust you're extending to strangers
Adding a package means shipping and maintaining its code and its entire transitive tree, and trusting its current and future maintainers. For small utilities the total cost — supply-chain surface, bundle weight, update churn, the occasional compromise — often exceeds writing the handful of lines yourself. Popularity raises the value of a package as an attack target rather than guaranteeing its safety.
- Make adding a dependency a reviewed decision weighing its transitive cost.
- Prefer fewer, well-maintained dependencies over many convenience micro-packages.
- Watch advisories, but triage by real exploitability in your usage, not raw severity.
QAInterview questions and model answers
Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.
Intermediate · Conceptual · 1 min · Question 1What are the two distinct entry points for supply-chain risk in a frontend project?Open model answer
Model answer
Install-time: a package or its postinstall script executes on the build machine or a developer's machine with that environment's privileges. Run-time: a third-party script executes in the user's browser inside your origin, with access to the DOM, cookies, and storage. They need different controls.
Open question page →Intermediate · Conceptual · 1 min · Question 2What does a committed lockfile with integrity hashes give you?Open model answer
Model answer
It pins the exact resolved version of every direct and transitive dependency and records a content hash, so every install reproduces the exact tree that was tested and a tampered package fails the integrity check. Installing with the frozen or CI flag enforces this rather than allowing re-resolution.
Open question page →Intermediate · Conceptual · 1 min · Question 3What does Subresource Integrity (SRI) protect against?Open model answer
Model answer
A compromised or malicious CDN serving altered content for a URL you trust. The browser hashes the fetched file and refuses to execute it if the hash doesn't match the integrity attribute, so a swapped script is blocked rather than silently run.
Open question page →Advanced · Conceptual · 1 min · Question 4Why isn't running npm audit enough on its own?Open model answer
Model answer
It lists known advisories against installed versions, but many findings aren't exploitable in your usage (a vulnerable code path you never call) and it misses malicious packages with no advisory yet. It's a triage input, not a verdict, and needs human judgment about real exposure.
Open question page →Intermediate · Conceptual · 1 min · Question 5How does loading a third-party widget in a sandboxed iframe reduce risk?Open model answer
Model answer
The iframe runs in a separate browsing context, so its script can't read the host page's DOM, cookies, or localStorage, and the sandbox attribute can further restrict what it may do. A compromise of the widget is contained to the iframe instead of the whole origin.
Open question page →Advanced · Conceptual · 1 min · Question 6How can CSP connect-src limit the damage of a compromised script?Open model answer
Model answer
Even if a malicious script runs, connect-src restricts which origins it can send network requests to, so it can't easily exfiltrate data to an attacker-controlled server. It's a containment layer for the case where prevention failed.
Open question page →Advanced · Conceptual · 1 min · Question 7What is dependency confusion (or substitution) and how is it mitigated?Open model answer
Model answer
An attacker publishes a public package with the same name as a company's private internal package and a higher version, hoping the resolver picks the public one. Mitigation includes scoped names, a registry configuration that pins internal scopes to the private registry, and explicit version constraints.
Open question page →Intermediate · Conceptual · 1 min · Question 8Why should adding a dependency be a reviewed decision?Open model answer
Model answer
Each dependency adds code you now ship and maintain, plus its own transitive tree, plus its maintainers as people you implicitly trust. For small utilities the cost of a dependency — supply-chain surface, bundle size, update burden — can exceed the cost of writing the few lines yourself.
Open question page →Advanced · Conceptual · 1 min · Question 9What's the risk of postinstall scripts?Open model answer
Model answer
They run arbitrary code automatically during npm install, on developer machines and CI, with the ability to read environment variables, credentials, and the filesystem. Some ecosystems and configurations let you disable script execution by default and allowlist the few packages that genuinely need it.
Open question page →Intermediate · Conceptual · 1 min · Question 10How do you respond when a dependency you use is reported as compromised?Open model answer
Model answer
Determine which versions are affected and whether your lockfile pins one, pin to a known-good version or remove the package, rotate any secrets that were exposed to build environments during the window, and check whether the malicious code ran in production or only at build time.
Open question page →SCScenario questions
Scenario 1
A popular utility package your app depends on transitively is reported to have shipped a malicious version for six hours two days ago that exfiltrates environment variables during install.
- Check the lockfile for the exact resolved version and its publish date.
- Determine whether any CI or developer install happened in the affected window.
- Pin to a known-good version and reinstall from a clean state.
- Rotate credentials that were present in affected build environments.
- Add script-execution controls and tighten review for transitive additions.
Reveal worked answer
First I'd check the committed lockfile to see exactly which version resolved and whether it falls in the malicious window, then look at CI run times and developer activity to see if an affected install actually happened. If it did, I treat any secret that was in those environments — deploy keys, tokens, registry credentials — as compromised and rotate them. I'd pin the dependency to a safe version, reinstall from scratch to verify the tree, and going forward disable postinstall scripts by default and require review for new transitive dependencies near sensitive tooling.