1. Courses
  2. Developer Foundations
  3. JavaScript in the Real World
  4. Stop 6

35 minAdvanced

Security and quality in JavaScript projects

A typical JavaScript project runs code from hundreds of strangers, ships its front end to every user's device, and puts user text on screens. Each of those is a door. This lesson shows how attackers use them, and the small set of habits and tools that keep them shut.

By the end you can

  • Explain how a malicious or hijacked npm package reaches production, and four defences against it
  • Read npm audit output and decide what to fix, pin or ignore
  • Spot and fix an XSS bug caused by innerHTML, and explain why eval is the same kind of risk
  • Move a secret out of front-end code into a server endpoint
  • Add security lint rules and use a short JavaScript review checklist

The everyday picture

A Mangrove Market distribution centre (DC) receives cartons from hundreds of suppliers every day. Most are honest. But the receiving team still checks each delivery against the purchase order: the right supplier, the right item codes, the seal intact, nothing extra in the carton. A carton that looks right but comes from a supplier with a slightly different name gets refused. A supplier whose truck was hijacked on the way can deliver a sealed carton with the wrong contents, so the team also checks samples and keeps records of what came from where.

Your node_modules folder is that DC. Every npm install is a delivery from many suppliers, and some of what arrives runs immediately, before anyone opens the carton. The receiving checks in this lesson are the lockfile (the purchase order), npm audit (the recall list), install script controls (not letting a carton unpack itself) and provenance (a sealed record of which factory made it).

The supply chain: you run strangers' code

A small Node project with ten direct dependencies often installs several hundred packages, because each dependency has its own. Any one of them can run code on a developer laptop, in CI, and in production. Attackers know this. The main routes are:

  • . In 2017 a package called crossenv imitated the popular cross-env. It worked like the real one and also sent the machine's environment variables (tokens, passwords) to the attacker. It went unnoticed for about two weeks.
  • Malicious install scripts. A package can declare a preinstall or postinstall script. Older npm versions run these automatically during npm install, with your user's permissions, before you have imported anything.
  • Compromised maintainers. On 8 September 2025, a maintainer of widely used packages such as chalk and debug entered his login and 2FA code on a fake npm site. The attacker published new versions with code that swapped crypto wallet addresses in browsers. The community noticed within about two hours. A week later a self-copying worm called Shai-Hulud used stolen tokens to inject post-install scripts into more packages; GitHub removed more than 500 of them.
  • Known vulnerabilities. No attacker involved: an honest package simply has a bug, such as a regular expression that takes minutes on certain input, or a merge function that allows prototype pollution (below).

The lockfile (Node.js and npm) is your first defence: npm ci installs exactly the versions and recorded in package-lock.json, so a new malicious version of a dependency cannot sneak in on the next CI run. It does nothing for a version that was already bad when you locked it, which is why the other defences exist.

Quick check

In which case does a committed lockfile with npm ci NOT protect you?

Attacker phished maintainer login publishes 4.2.1 npm registry bad version is latest npm install ^4.2.0 Laptop or CI postinstall runs steals tokens Secrets leak npm, GitHub, cloud keys code is bundled Production runs in every POS Where it stops release age wait 7 days lockfile + ci block scripts short tokens least privilege review diffs audit, pin
A supply-chain attack path. A hijacked maintainer account publishes a bad version. An install that is not locked pulls it, its install script runs and steals tokens, and the code ships to production. Each green box is a defence that breaks the chain at that step.

Loading the rest of the lesson…