Skip to content

Scripts From a CDN

JavaScript Loaded From a Content Delivery Network

JavaScript a page loads from another domain, run in every visitor's browser.

  • Delivery

About

Many pages load scripts straight from someone else's server, such as a library from a public CDN, analytics, or a chat or payment widget. The browser runs whatever that server sends, so whoever controls the server controls code on the page. It runs with everything the page can see, including what visitors type.

The script runs in every visitor's browser on every page view, in whatever form its server sends, unless the page pins the exact file and checks its hash.

If It Is Malicious

If a script loaded from a CDN is malicious, it runs in the visitor's browser with everything the page can see and do, on every site that loads it, for every visitor.

See It in the Stack

Examples

These are well-known names from Scripts From a CDN, written as you would meet them in an inventory, an alert or a lockfile, the file that records every version a build installed.

cdnjs
A free, open-source CDN for libraries, powered by Cloudflare.
jsDelivr
A free CDN that serves files from npm and GitHub.
unpkg
Serves any file from any npm package by its address.
Google Tag Manager
Loads analytics and marketing tags that marketing teams can change.
polyfill.io
A script service that turned malicious after it was sold in 2024.

How Bad Code Gets In

These are the ways bad code can reach your systems through Scripts From a CDN. None of them needs a flaw in your own code, so outside code needs checking as much as your own.

  • The domain or service behind a script changes hands, and the new owner serves bad code.
  • A supplier's server is broken into and its script is changed.
  • A page loads the latest version of a package from a CDN, so a bad npm release reaches every visitor at once.

How to Check

These checks show what came from Scripts From a CDN, whether a known bad version is in use, and how to keep one out next time.

  • List every third-party script your pages load, and remove the ones you do not need.
  • Pin exact versions and add Subresource Integrity hashes, a fingerprint of each file that the browser checks, so a changed file is refused.
  • Set a Content Security Policy that allows scripts only from domains you have chosen.
  • Host the files yourself where you can, so a third party's change cannot reach your pages.
  • Keep third-party scripts off payment and sign-in pages.

Well-Known Incidents

Each incident below is a real case, told at the level of its public advisory. The tag says how the bad code got in, and the link opens the primary source.

  • Compromised Build or Release2018

    Ticketmaster Chat Widget

    Attackers broke into a chat widget that a supplier hosted on Ticketmaster's payment page, and used it to reach customers' card details.

    Reach Card details of customers who paid on that page were exposed, and banks reported fraud. The UK regulator later fined Ticketmaster for failing to assess the risk of a third-party chat widget on its payment page.

    Source: webarchive.nationalarchives.gov.uk (opens in a new tab)
  • Domain Changed Hands2024

    polyfill.io

    The polyfill.io domain and service were sold to a new owner, which began serving script that sent some mobile visitors to scam sites.

    Reach A great many sites loaded it straight from the domain into every visitor's browser, until the registrar took the domain down.

    Affectedcdn.polyfill.io

    Source: sansec.io (opens in a new tab)

In Common Stacks

These common stacks take code from Scripts From a CDN. Open one to see where that code sits among its layers and who runs each one.

Sources

Product names and logos are trademarks of their owners, shown only to name each product, with no endorsement implied. npm is a registered trademark of npm, Inc.

Apache, Apache HTTP Server, Tomcat and Log4j are trademarks of the Apache Software Foundation. Node.js® is a registered trademark of the OpenJS Foundation, and Kubernetes® of LF Projects, LLC.

Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries. Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.

MongoDB® is a registered trademark of MongoDB, Inc. Redis® is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd.

PHP logo by Colin Viebrock, CC BY-SA 4.0 (opens in a new tab). Ruby logo © 2006 Yukihiro Matsumoto, CC BY-SA 2.5 (opens in a new tab). Tux by Larry Ewing, with Garrett LeSage and IFo Hancroft.

Puma logo © Evan Phoenix and contributors, CC BY-ND 3.0 (opens in a new tab). NuGet logo from NuGet's Media repository, CC BY 2.0 (opens in a new tab).

Gunicorn logo © Benoît Chesneau and Paul J. Davis, MIT licence for the Gunicorn logo (opens in a new tab). Packagist logo © 2011 Jordi Boggiano and Nils Adermann, MIT licence for the Packagist logo (opens in a new tab).

MIT Licence Notices for the Gunicorn and Packagist Logos

Gunicorn logo

2009-2024 (c) Benoît Chesneau <benoitc@gunicorn.org> 2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Packagist logo

Copyright (c) 2011 Jordi Boggiano, Nils Adermann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.