Strengthening Security Scanning with CodeQL and yarn npm audit

2026-05-20 hit count image

Two threats that supply chain cooldown alone cannot stop — newly discovered CVEs in already-installed dependencies, and vulnerabilities in your own code — and how to address them with yarn npm audit and GitHub CodeQL, illustrated with real incident examples.

web

Introduction

The supply chain defense series established that cooldown is a time-based gate against “freshly published malicious versions.” But two things fall outside the cooldown’s scope:

  1. Newly discovered CVEs in packages already in the dependency tree — vulnerabilities found long after a version was published and deemed legitimate
  2. Vulnerabilities in our own code — own-code flaws such as XSS, prototype pollution, and injection

This article covers the two scanners best suited to address each of these threats: yarn npm audit and GitHub CodeQL.

What Are the Risks?

Risk 1: New CVEs in Already-Installed Dependencies

Cooldown only operates at the point of new publication. But security vulnerabilities are more commonly discovered months or even years after a version was first published. Representative examples:

  • Log4Shell (2021, CVE-2021-44228): A critical RCE discovered in Log4j after 8 years of considered-safe usage
  • lodash prototype pollution (CVE-2019-10744): A prototype pollution vulnerability found in lodash after years of stable use
  • xmldom and other XML parser vulnerabilities: XXE/RCE issues discovered periodically in long-running libraries

This class of risk requires answering the question: “Do any of the dependencies we are currently using have known CVEs?

Risk 2: Vulnerabilities in Our Own Code

Even with strong supply chain defenses, flaws in the code we write ourselves create their own attack paths:

  • Inserting user input directly into the DOM via innerHTML → XSS
  • Failing to validate __proto__ keys when merging objects → prototype pollution
  • Catastrophic backtracking in a regular expression → ReDoS
  • User input in a dynamic import() path → import injection

Supply chain cooldown can never catch these. Static analysis of your own code is what surfaces them.

yarn npm audit: Detecting Known CVEs in Dependencies

yarn npm audit matches the lockfile’s dependencies against the GitHub Advisory Database and identifies known CVEs. Adding it as a gate in the PR stage means the PR will fail whenever a new CVE appears in the dependency tree.

Adding It to a CI Workflow

# .github/workflows/check_audit.yml
name: Dependency Audit
on:
  pull_request:
  schedule:
    - cron: '0 0 * * *'   # check once per day

permissions:
  contents: read

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<SHA> # v6
      - uses: actions/setup-node@<SHA> # v6
      - run: corepack enable
      - run: yarn install --immutable
      - run: yarn npm audit --severity high --recursive

Option reference:

OptionDescription
--severity highOnly fail on high severity or above
--recursiveScan all workspaces in a monorepo

Effect

  • When a new CVE is registered, the next PR or next daily cron run will fail immediately
  • “Does this CVE affect us?” gets answered automatically every day
  • If false positives are too noisy, --severity critical can narrow the threshold further

CodeQL: Detecting Vulnerabilities in Your Own Code

GitHub CodeQL is free for public repositories. For private repositories, it is available through GitHub Code Scanning (requires a GitHub Advanced Security license).

CodeQL converts source code into a database, then runs security queries (hundreds of pre-defined rules) against it like SQL to find vulnerabilities. For JavaScript and TypeScript, it is particularly effective at catching:

  • XSS (reflected, stored, and DOM-based)
  • Prototype pollution
  • ReDoS (regular expression denial of service)
  • Unsafe deserialization
  • Injection (SQL, command, path traversal, etc.)

Adding It to a CI Workflow

# .github/workflows/codeql.yml
name: CodeQL
on:
  push:
    branches: [main]
  pull_request:
  schedule:
    - cron: '0 0 * * 1'   # full scan every Monday

permissions:
  contents: read
  security-events: write

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<SHA> # v6
      - uses: github/codeql-action/init@<SHA>
        with:
          languages: javascript-typescript
      - uses: github/codeql-action/analyze@<SHA>

Analysis results appear in the “Code scanning alerts” section of GitHub’s Security tab, and inline comments are automatically added to PRs.

Real-World Impact

GitHub Security Lab runs a Community CodeQL Bounty Program where community-authored CodeQL queries have been used to discover numerous CVEs in real open-source projects. For JavaScript and TypeScript, pre-defined security queries routinely surface new instances of prototype pollution, ReDoS, XSS, and unsafe deserialization patterns.

A collection of specific findings is available on the GitHub Security Lab CodeQL Wall of Fame.

How the Two Scanners Divide Responsibility

ToolWhat it scansWhat it catches
yarn npm auditLockfile dependenciesKnown CVEs — vulnerabilities in the advisory database
CodeQLOwn source codeUnknown own-code flaws — XSS, injection, prototype pollution
(Reference) cooldownNewly published versionsMalicious new publishes — backdoors just uploaded to npm
(Reference) SemgrepOwn source code (complementary)Code style and secure pattern enforcement

All three address different threats. None of them can substitute for the others.

Limitations

  • False positives in yarn npm audit: Many flagged vulnerabilities are in code paths that are present in the dependency tree but never actually called in practice. Failing PRs on those creates noise. Adjust the --severity threshold, and treat the final impact assessment as a human judgment call.
  • CodeQL analysis time: In a large monorepo, a CodeQL analysis can take tens of minutes. If running it on every PR is too costly, a reasonable trade-off is to run it only on push and weekly cron.
  • Undiscovered CVEs: Both scanners catch “already known” flaws. Zero-days are a separate problem.

Conclusion

Cooldown filters out new malicious publishes. yarn npm audit and CodeQL catch risks that are already inside the tree or that we built ourselves. All three are needed for a truly layered supply chain security posture.

  • For the quickest win, add yarn npm audit as a PR gate. One setup and you’re done.
  • CodeQL takes more time but is highly effective at finding own-code vulnerabilities. A gradual rollout — starting with a weekly cron and later moving to a PR gate — is recommended.

References

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

App promotion

You can use the applications that are created by this blog writer Deku.
Deku created the applications with Flutter.

If you have interested, please try to download them for free.



SHARE
Twitter Facebook RSS