Skip to content

[CI][SECURITY] The dependency audit gate never runs — 19 high advisories accumulated behind a SKIPPED job #2502

Description

@dcccrypto

Summary

playground has 19 high-severity dependency advisories. The CI gate that would
have caught them exists, runs pnpm audit --audit-level=high, and never
executes
— so the check reports green while the findings accumulate.

This is the #2447 pattern again, but on the security audit rather than the test
suites, which is why it has been invisible for longer.

The gate, and why it is dead

# .github/workflows/test.yml:270
- name: Run security audit
  run: pnpm audit --audit-level=high

That step is inside the security-tests job (test.yml:242). Every PR shows:

Unit Tests: SKIPPED   Integration Tests: SKIPPED
Security Tests: SKIPPED   Coverage Gate: SKIPPED
✅ Merge Gate: SUCCESS

security-tests is gated on packages/*, which no longer exists on playground
or main — the file says so itself, a few lines below the job:

The app's own suite (2702 tests). Every other test job above is gated on
packages/*, which no longer exists on playground or main …

#2450 fixed that for the app suite. security-tests was left behind, and it
is the job carrying the dependency audit.

Current findings

pnpm audit --audit-level=high on playground:

44 vulnerabilities found
Severity: 3 low | 23 moderate | 18 high (1 ignored)

(19 high before #2501, which closes brace-expansion.)

High findings span:

package likely remediation
brace-expansion override — done in #2501
fast-uri override
ip-address override
postcss override
socket.io-parser override
undici may need a transitive-parent upgrade
sharp likely a real upgrade
next framework upgrade — needs its own assessment

I have deliberately not bundled these. next and sharp are not one-line
overrides, and an override that pins a framework transitively is its own risk.

Suggested direction

  1. Make the gate run. Whatever security-tests becomes, the audit step needs
    to execute on PRs — otherwise this recurs silently. Note it will fail
    immediately, so it likely wants to land after (or alongside) the override
    batch, or start non-blocking with a deadline.
  2. Batch the override-able ones (fast-uri, ip-address, postcss,
    socket.io-parser) — mechanical, one PR.
  3. Assess next / sharp / undici separately — real upgrades with real
    blast radius.

Note on overrides as a mitigation

brace-expansion illustrates the failure mode worth designing against: the repo
already had an override (>=5.0.7 <6), added for an earlier advisory. A newer
advisory then raised the patched floor past it, and the <6 ceiling guaranteed
the pin could not drift forward on its own. An override is a point-in-time
assertion; it does not stay true.
Ceilings on security floors are worth avoiding,
and a running audit is what catches the ones that go stale anyway.

Same class was live in percolator-indexer (fixed in indexer#193) — and there it
was CI-blocking, because that repo's audit gate does run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions