BiTree
  • Search For Lessons
  • Curriculum
  • Pricing
  • For Educators
  • Become a Tutor
  • About
  • Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
BiTree

Live coding lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Search For Lessons
  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Become a Tutor
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 BiTree. All rights reserved.
Curriculum/Web Development/Security for Developers/Dependency Security and Supply Chain
40 minIntermediate

Dependency Security and Supply Chain

After this lesson, you will be able to: Audit project dependencies with npm audit, automate updates with Dependabot, add Snyk scanning to CI, understand why lockfiles belong in version control, and treat every dependency as attack surface.

Most of your app is code you did not write. A supply-chain attack compromises you through a dependency. This lesson covers real incidents (event-stream, XZ Utils, left-pad), npm audit, Dependabot, Snyk in CI, lockfiles, and the discipline of minimal dependencies.

Prerequisites:Git, GitHub, and Your First Repo

What a supply-chain attack is, with real examples

A supply-chain attack compromises you by compromising something you depend on. event-stream (2018): a popular package was handed to a new maintainer who added code to steal Bitcoin wallets. XZ Utils (2024): a multi-year social-engineering campaign planted a backdoor in a core Linux compression library, nearly reaching every server on earth before a developer noticed a tiny performance anomaly. left-pad (2016): an 11-line package was unpublished and broke builds across the internet, showing how much rests on tiny, unowned dependencies. These are not hypotheticals.

npm audit: what it checks and how to read it

npm audit cross-references your dependency tree against a vulnerability database and reports severity.

bash
$ npm audit
# found 3 vulnerabilities (1 low, 1 moderate, 1 high)
$ npm audit fix # applies safe, in-range updates
$ npm audit fix --force # may install breaking major versions: review first
# For a finding you cannot fix yet (no patch upstream):
# - assess whether the vulnerable code path is even reachable in your app
# - document the decision; revisit when a patch ships

Dependabot and Snyk

Dependabot (built into GitHub) opens automated pull requests when a dependency has an update or a known vulnerability. Configure update frequency in .github/dependabot.yml, review the changelog, let CI run, and merge. Snyk goes further than npm audit: it catches issues in transitive dependencies, suggests minimal upgrade paths, and integrates as a GitHub Actions step that can fail the build on a high-severity finding. The free tier covers individual and small projects.

Snyk as a CI gate

A minimal GitHub Actions step that fails the build on high-severity issues.

tsx
# .github/workflows/security.yml
- name: Snyk dependency scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high

Lockfiles and minimal dependencies

package-lock.json and yarn.lock pin the exact version of every dependency, including transitive ones, so every install and every CI run gets the identical tree. Commit them. Deleting and regenerating a lockfile is sometimes a deliberate security step (to pull patched transitive versions), but normally you keep it stable. The deeper discipline: every dependency is attack surface and maintenance burden. Before adding a package ask: does this justify the risk, is it actively maintained, and how many transitive dependencies does it drag in? Sometimes ten lines of your own code beats a package with forty sub-dependencies.

Quick Check

Why does package-lock.json belong in version control?

Pick the best reason.

Common mistakes only experienced devs catch

Running npm audit fix --force without reading what it changes, and shipping a breaking major bump. Ignoring audit output entirely because 'it is just dev dependencies' (build-time compromise is still compromise). Not committing the lockfile, so CI installs a different tree than you tested. Adding a heavy package for a one-line need. Auto-merging Dependabot PRs without CI, so a bad update ships unreviewed. Assuming a high download count means a package is safe (event-stream was hugely popular).

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Secure Authentication Practices
Back to Security for Developers
HTTPS, TLS, and DNS Security→