---
title: Third-party scripts and dependencies
summary: Every script you load from someone else runs with your page's full power. Real breaches that came in through a chat widget, a CDN and an npm package.
topic: security
order: 6
updated: 2026-09-19
---

## What it is

A `<script src="https://someone-else.com/x.js">` tag hands that other company the keys to
your page. Their code can read every form field, every price and every piece of data on
screen, and send it anywhere. The same goes for every npm package in your server: it runs
with your database password in memory.

This is the **supply chain**: code you did not write, running as if you did.

## Why it is a rule

- **British Airways (2018).** Attackers changed about 22 lines of a JavaScript file on the
  payment page. For two weeks it copied card details as customers typed them. Around 400,000
  people were affected, and the UK regulator fined BA £20 million.
- **Ticketmaster (2018).** The skimmer came in through a third-party chat widget on the
  payment pages. Ticketmaster had not written the code that stole its customers' cards.
- **polyfill.io (2024).** A popular script CDN was sold to a new owner, who began serving
  malicious code to the more than 100,000 sites that still loaded it.
- **event-stream (2018).** The maintainer of an npm package with millions of weekly downloads
  handed it to a stranger, who added a dependency that tried to steal from a specific bitcoin
  wallet app.

## How to do it

### Serve it yourself

If a file can live on your own server, put it there. A copy you host cannot be changed under
you by someone else, and it keeps working when their CDN is slow or blocked.

### Pin it with Subresource Integrity

When a script must come from a CDN, pin the exact bytes you reviewed:

```html
<script src="https://cdn.jsdelivr.net/npm/lib@4.2.1/dist/lib.min.js"
        integrity="sha384-…"
        crossorigin="anonymous"></script>
```

If the file changes by one byte, the browser refuses to run it.

### Keep secrets away from third-party code

Pages that show private data (dashboards, books, payments) load the fewest outside scripts,
ideally none. An analytics tag has no business on a page that shows a client's ledger.

### Lock and review dependencies

- Commit the lockfile, and install with `npm ci` so the build uses exactly those versions.
- Look at a new package before adding it: who maintains it, how many dependencies it pulls
  in, when it last changed.
- Fewer dependencies is a security feature.

### Keep a list

Every outside script, font, pixel and API: what it receives, where it sends it, and why you
need it. The privacy policy names each one.

## How we do it here

The public site self-hosts its fonts, icons and scripts. Part of the reason is security, and
part is that third-party hosts often fail behind the TLS-intercepting proxies common on
Philippine networks. Pages that show client data do not load analytics or marketing tags.

## Benefits

- Removes a whole path an attacker can use without ever touching your server.
- Self-hosted files load from the same connection, often faster.
- Fewer outside parties means a shorter, more honest privacy policy.

## Disadvantages

- You patch what you host. A self-hosted library does not update itself.
- SRI breaks when a CDN legitimately changes a file, and you have to update the hash.
- Some services (payments, maps, captchas) only work from their own domain.

## Checklist

- Every outside script is on the list, with a reason.
- CDN scripts carry `integrity`.
- No third-party tags on pages that show private data.
- Lockfile committed; installs use `npm ci`.

## Sources

- [MDN — Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)
- [OWASP — Third Party JavaScript Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Third_Party_Javascript_Management_Cheat_Sheet.html)
- UK Information Commissioner's Office, penalty notice to British Airways, October 2020.
