Skip to content

Triage 5 open Dependabot high-severity alerts #50

@byapparov

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions