In this chapter
We'll learn how the packages your project depends on can bring vulnerabilities with them, how to manage dependencies safely, and the security mindset that ties everything together — then finally stop Monday's bots.
The Problem in Real Life
Anna runs npm audit on BlueTicket's web app for the first time. The terminal fills with text: 14 vulnerabilities (2 high, 9 moderate, 3 low). One high one is in a package she's never heard of — something a package that another package uses depends on.
Meanwhile, Monday's bots are still the open card on the corkboard. Samantha has a big on-sale next week. "Can we stop them before then?"
You didn't write most of the code you ship. You're still responsible for it.
John
Trusting Every Package Forever vs. Managing Them Like Ingredients
Most code is someone else's
A modern app is mostly packages written by strangers (Act 16) — and their dependencies.
Vulnerabilities are found later
A package that was safe last year can have a known hole today.
Some packages are traps
Attackers publish fake packages with names one letter away from popular ones.
Dependency Vulnerabilities, Secure Dependency Management and the Security Mindset
The restaurant supplier analogy: a restaurant doesn't grow its own vegetables. It buys from suppliers — and if one supplier sends contaminated spinach, the restaurant's customers get sick, not the supplier's. So good restaurants know their suppliers, check deliveries, react fast to food-safety recalls, and don't buy from an unknown van with a familiar-looking logo. Dependencies are your code's suppliers.
- Dependency vulnerabilities — the recall notices: security researchers keep finding holes in popular packages. Each known hole gets a public ID (a CVE) and a severity. If your app uses an affected version — directly or as a transitive dependency (Act 16) — your app has that hole, even though you never wrote that code.
- Finding them — automated checks: tools compare your lock file (Act 16) with databases of known vulnerabilities:
npm audit,pip-audit, GitHub's Dependabot, Snyk and others. Dependabot can even open pull requests that update a vulnerable package for you. Container images get scanned in the pipeline too (Act 21). - Fixing them — update, test, ship: most fixes are simply updating to a patched version — usually a PATCH or MINOR update (Act 16's SemVer). Run the tests (Act 17), ship through the pipeline (Act 19). Not every warning is urgent: check whether the vulnerable code is actually reachable in your app, and fix high-severity, reachable ones first.
- Secure dependency management — choosing suppliers well: fewer dependencies means fewer suppliers to trust; before adding one, check it's maintained and widely used. Watch for typosquatting — fake packages like
expresssorreqeuststhat contain malware. Always commit the lock file and install withnpm ci, so a surprise new version can't sneak in. Keep dependencies updated regularly, a little at a time, rather than all at once every two years. - The security mindset — thinking like an attacker: for every feature, ask: who could misuse this, and how? What could someone type here? What if someone does this a million times? What if this key leaks? Then defend in layers — defence in depth, like a castle with a moat, walls and guards: validation, then parameterised queries, then least-privilege database accounts, then monitoring. If one layer fails, the next catches it.
- Abuse of normal features — Monday's bots: the bots didn't break in; they used the site normally, just inhumanly fast. The defence is rate limiting (only so many requests per second from one IP or account), business limits (a maximum number of tickets per account per show), bot detection and challenges (CAPTCHAs) when behaviour looks automated, and for huge on-sales a virtual waiting room that lets fans in at a steady pace (Act 14's queue idea).
| Layer | What it does | Stops |
|---|---|---|
| Rate limit: 10 req/s per IP | Slows any single source down | Simple bots hammering the site |
| 6 tickets per account per show | Business rule on the server | One account buying a whole row |
| Challenge on suspicious behaviour | CAPTCHA when patterns look automated | Bots using many accounts |
| Virtual waiting room | Lets fans in at a steady pace | Everyone rushing at 10:00:00 |
| Monitoring | Alerts on unusual buying patterns | New tricks we haven't seen yet |
| Ask | Example at BlueTicket |
|---|---|
| What could someone type here? | ' OR 1=1 -- in the promo code |
| What if they do it a million times? | Bots buying front rows |
| What if this secret leaks? | A restricted key limits the damage |
| Who should be allowed to do this? | Refunds: only the refunds service and admins with MFA |
| How would we notice? | Alerts, logs, audit trails |
npm audit # list known vulnerabilities in the lock filenpm audit --audit-level=high # fail (exit code 1) if any high or critical are foundnpm update date-fns # update within the allowed rangenpm ls minimist # which package pulled this one in?
The dependency fixes: Anna updates the two high-severity packages (both PATCH updates), runs the tests, ships them. She turns on Dependabot for every repository, adds npm audit --audit-level=high to the pipeline so new high-severity issues fail the build, and the team agrees to merge dependency updates every week.
The bots, stopped: the team adds a rate limit of 10 requests per second per IP on ticket endpoints, a limit of 6 tickets per account per show, a challenge when one account tries many cards, and a waiting room for the biggest on-sales. Next week's on-sale: the front rows go to 1,800 different fans instead of 40 bot accounts. Resale listings for those seats drop almost to zero.
The close: on Friday, the corkboard has three cards with green ticks: key rotated, input parameterised, bots rate-limited. Samantha asks if they're "secure now". Anna answers the way John taught her: "Safer than Monday. Security isn't a finish line — it's a habit. But we've got the habit now."
Key Takeaway
Most code you ship is other people's packages — and their known vulnerabilities become yours. Scan your lock file automatically (npm audit, Dependabot) and in the pipeline, update in small regular steps, add few and well-known dependencies, and watch for typosquatting. Think like an attacker — what could someone type here, what if they do it a million times — and defend in layers. Abuse of normal features, like scalper bots, needs rate limits, business limits, bot challenges and queues.
Why This Matters
Vulnerable and malicious dependencies are now one of the most common ways real systems are attacked, and keeping dependencies healthy is part of every developer's routine. The security mindset — asking how something could be misused and defending in layers — is what turns all the techniques in this Act into everyday habits.
Three attacks, three fixes, and a new way of looking at every form. John hands Anna one last exercise: look at BlueTicket's login and checkout through an attacker's eyes — before an attacker does.
