Skip to content

Triage 5 open Dependabot high-severity alerts #50

Description

@byapparov

Dependabot is reporting 5 open high-severity alerts on main. I triaged each against the current codebase while investigating the v0.3.2 release pipeline. Below is the full picture so whoever picks this up isn't starting from scratch.

TL;DR

# Package GHSA CVSS In-repo exploitability Action
1 drizzle-orm@1.0.0-beta.12-a5629fb GHSA-gpj5-g38j-94v9 7.5 None reachable — local SQLite only, no sql.identifier()/.as() with user input Bump to 1.0.0-beta.21+
2 minimatch@10.0.3 GHSA-7r86-cg39-jmmj 7.5 Low — patterns come from local config file Bump to 10.2.3
3 minimatch@10.0.3 GHSA-23c5-xmqv-rm74 7.5 Same as #2 Same bump clears it
4 minimatch@10.0.3 GHSA-3ppc-4f35-3m26 (unscored, ReDoS) Same as #2 Same bump clears it
5 @modelcontextprotocol/sdk@1.25.2 GHSA-345p-7cg4-v4c7 7.1 None — we're an MCP client, advisory is server-side Bump to 1.26.0+ for hygiene

All three root packages live in packages/cli/package.json. None of the advisories are currently exploitable in production use of the CLI, but the versions are plain out-of-date and should be bumped.


Alert 1: drizzle-orm SQL injection via identifier escaping

  • Advisory: GHSA-gpj5-g38j-94v9 — Drizzle ORM improperly escapes quoted SQL identifiers in dialect-specific escapeName(). sql.identifier() / .as() with attacker-controlled input enables injection.
  • Current: drizzle-orm@1.0.0-beta.12-a5629fb in packages/cli/package.json, drizzle-kit@1.0.0-beta.12-a5629fb in packages/cli/package.json and the root package.json workspace catalog. Plus a pinned override "drizzle-orm": "1.0.0-beta.12-a5629fb" in packages/cli/package.json's overrides.
  • Vulnerable ranges (from advisory):
    • < 0.45.2 → fixed in 0.45.2
    • >= 1.0.0-beta.2, < 1.0.0-beta.20 → fixed in 1.0.0-beta.20 ← we're in this range
  • Target: 1.0.0-beta.21 (current beta dist-tag on npm). All three declarations need to stay in sync.
  • Exploitability in this codebase: grep -rn 'sql\.identifier\|\.as(' packages/cli/src/ returns zero hits. The CLI uses drizzle purely with hardcoded table definitions (sqliteTable(...), eq()) against a local bun-sqlite database. There is no dynamic identifier path reachable from user input or network.
  • Why bump anyway: stale pinned betas are the wrong kind of boring; easy to miss if the exploitation surface changes later.

Alerts 2, 3, 4: minimatch ReDoS (three distinct patterns)

  • Advisories:
    • GHSA-7r86-cg39-jmmj — multiple non-adjacent ** segments, O(C(n,k)) backtracking
    • GHSA-23c5-xmqv-rm74 — nested *() extglobs (most severe; 12-byte minimum trigger)
    • GHSA-3ppc-4f35-3m26 — long runs of * + non-matching literal, O(4^N)
  • Current: minimatch@10.0.3
  • Target: 10.2.3 (all three advisories clear at this version — note GHSA-3ppc says fixed in 10.2.1, but the other two gate to 10.2.3, so 10.2.3 is the minimum to close all alerts)
  • Usage surface:
    • packages/cli/src/util/glob.ts:32 — direct minimatch() call in Glob.match(pattern, filepath). Callers of Glob.match: only packages/cli/src/file/ignore.ts (Ignore.match). Callers of Ignore.match: zero. This is dead code.
    • packages/cli/src/util/glob.ts:24 and scanSync — delegate to the glob package which uses minimatch transitively. This is actively used (20+ call sites).
  • Where do patterns come from?
    • All Glob.scan calls except two use hardcoded literal patterns ("**/*.ts", "storage/session/...", etc.)
    • packages/cli/src/util/filesystem.ts:198 Filesystem.globUp(pattern, ...) — pattern is a parameter
    • Callers of globUp: only packages/cli/src/session/instruction.ts:32,40, where the pattern is instruction from config.instructions (the user's local config file)
  • Practical risk: to trigger a ReDoS, an attacker must edit the user's config file to add a catastrophic glob pattern. An attacker with local config-write access can already do much worse. Low priority for actual exploitability, but the dead Glob.match path is worth deleting anyway while we're here.

Alert 5: @modelcontextprotocol/sdk cross-client data leak

  • Advisory: GHSA-345p-7cg4-v4c7 — two issues in stateless deployments:
    1. Reusing a single StreamableHTTPServerTransport across multiple client requests (JSON-RPC message ID collisions leak responses)
    2. Reusing a single McpServer/Server instance across multiple transports
  • Current: @modelcontextprotocol/sdk@1.25.2
  • Target: 1.26.0 or later
  • Exploitability in this codebase: grep -rn 'StreamableHTTPServerTransport\|new McpServer\|new Server' packages/cli/src/ returns zero hits. The aictrl CLI is an MCP client — it connects to MCP servers configured by the user, it doesn't run one. The server-side instance-reuse bug simply doesn't apply.
  • Why bump anyway: low-risk hygiene; defends against a future architecture change that introduces a server path.

Suggested plan

One PR, three coordinated bumps:

  1. drizzle-orm1.0.0-beta.21 (or newer, wherever the beta dist-tag currently points) in all three declaration sites, keeping drizzle-kit in sync. Verify the overrides block still matches. Refresh bun.lock.
  2. minimatch10.2.3 in packages/cli/package.json. Refresh bun.lock.
  3. @modelcontextprotocol/sdk1.26.0+ in packages/cli/package.json. Refresh bun.lock.
  4. Run bun turbo typecheck and the db migration tests — drizzle beta bumps are the most likely to break, since beta-track versions can ship breaking API changes between patches.

Optional but good hygiene while we're touching this: delete Glob.match + Ignore.match from util/glob.ts and file/ignore.ts since they're confirmed dead code (unrelated to the advisory fix, but surfaced during triage).

Investigation commands used

gh api repos/aictrl-dev/cli/dependabot/alerts --paginate    # full alert list
grep -rn 'sql\.identifier\|\.as(' packages/cli/src/         # drizzle-orm exploitability
grep -rn 'Glob\.match\|minimatch(' packages/cli/src/        # minimatch reachability
grep -rn 'StreamableHTTPServerTransport' packages/cli/src/  # MCP server check

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions