CVE-2026-82367 (GCVE-0-2026-82367)
Vulnerability from cvelistv5
Published
2026-08-30 18:17
Modified
2026-08-30 18:17
CWE
  • CWE-488 - Exposure of Data Element to Wrong Session
Summary
Exposure of Data Element to Wrong Session vulnerability in ash-project ash_graphql can deliver one subscription's resolved records to a different subscriber's topic. AshGraphql.Subscription.Batcher.do_send/5 reads the resolved batch from the process dictionary via Process.get(:batch_resolved) and then unconditionally deletes it. That is sound only inside a task the library owns. On the :backpressure_sync and :noproc fallbacks do_send/5 runs inline in the publishing caller's process, so if a resolver inside an outer do_send/5 triggers another synchronous Ash notification, the inner call finds the outer run's value still under :batch_resolved, adopts it as its own result, and publishes it to the inner topic, a different subscription document with a different actor and tenant. It then deletes the key, so the outer run publishes nothing. The key is not namespaced by run, so records cannot be told apart. The fix saves, clears, and restores :batch_resolved around each run. This issue affects ash_graphql: from 1.4.0 before 1.11.0.
Impacted products
Vendor Product Version
ash-project ash_graphql Version: 1.4.0   
    cpe:2.3:a:ash-project:ash_graphql:*:*:*:*:*:*:*:*
Create a notification for this product.
   ash-project ash_graphql Version: 3cb2c9870d050c7c4bba6c211aaed97d732f7e81
    cpe:2.3:a:ash-project:ash_graphql:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:ash-project:ash_graphql:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.AshGraphql.Subscription.Batcher\u0027"
          ],
          "packageName": "ash_graphql",
          "packageURL": "pkg:hex/ash_graphql",
          "product": "ash_graphql",
          "programFiles": [
            "lib/subscription/batcher.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.AshGraphql.Subscription.Batcher\u0027:do_send/5"
            }
          ],
          "repo": "https://github.com/ash-project/ash_graphql",
          "vendor": "ash-project",
          "versions": [
            {
              "lessThan": "1.11.0",
              "status": "affected",
              "version": "1.4.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:ash-project:ash_graphql:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.AshGraphql.Subscription.Batcher\u0027"
          ],
          "packageName": "ash-project/ash_graphql",
          "packageURL": "pkg:github/ash-project/ash_graphql",
          "product": "ash_graphql",
          "programFiles": [
            "lib/subscription/batcher.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.AshGraphql.Subscription.Batcher\u0027:do_send/5"
            }
          ],
          "repo": "https://github.com/ash-project/ash_graphql",
          "vendor": "ash-project",
          "versions": [
            {
              "lessThan": "b798ef5288664a0261990b19765558f168b718fb",
              "status": "affected",
              "version": "3cb2c9870d050c7c4bba6c211aaed97d732f7e81",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThe application uses \u003ccode\u003eash_graphql\u003c/code\u003e subscriptions where a subscription resolver\u0027s execution can itself emit an Ash notification, and delivery takes the synchronous \u003ccode\u003e:backpressure_sync\u003c/code\u003e or \u003ccode\u003e:noproc\u003c/code\u003e (missing-batcher) path rather than a library-owned task.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "The application uses `ash_graphql` subscriptions where a subscription resolver\u0027s execution can itself emit an Ash notification, and delivery takes the synchronous `:backpressure_sync` or `:noproc` (missing-batcher) path rather than a library-owned task."
            }
          ],
          "value": "The application uses ash_graphql subscriptions where a subscription resolver\u0027s execution can itself emit an Ash notification, and delivery takes the synchronous :backpressure_sync or :noproc (missing-batcher) path rather than a library-owned task."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:ash-project:ash_graphql:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.11.0",
                  "versionStartIncluding": "1.4.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "reporter",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Zach Daniel / Ash Project"
        },
        {
          "lang": "en",
          "type": "coordinator",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eExposure of Data Element to Wrong Session vulnerability in ash-project ash_graphql can deliver one subscription\u0027s resolved records to a different subscriber\u0027s topic.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshGraphql.Subscription.Batcher.do_send/5\u003c/code\u003e reads the resolved batch from the process dictionary via \u003ccode\u003eProcess.get(:batch_resolved)\u003c/code\u003e and then unconditionally deletes it. That is sound only inside a task the library owns. On the \u003ccode\u003e:backpressure_sync\u003c/code\u003e and \u003ccode\u003e:noproc\u003c/code\u003e fallbacks \u003ccode\u003edo_send/5\u003c/code\u003e runs inline in the publishing caller\u0027s process, so if a resolver inside an outer \u003ccode\u003edo_send/5\u003c/code\u003e triggers another synchronous Ash notification, the inner call finds the outer run\u0027s value still under \u003ccode\u003e:batch_resolved\u003c/code\u003e, adopts it as its own result, and publishes it to the inner \u003ccode\u003etopic\u003c/code\u003e, a different subscription document with a different actor and tenant. It then deletes the key, so the outer run publishes nothing. The key is not namespaced by run, so records cannot be told apart. The fix saves, clears, and restores \u003ccode\u003e:batch_resolved\u003c/code\u003e around each run.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_graphql: from 1.4.0 before 1.11.0.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Exposure of Data Element to Wrong Session vulnerability in ash-project ash_graphql can deliver one subscription\u0027s resolved records to a different subscriber\u0027s topic.\n\n`AshGraphql.Subscription.Batcher.do_send/5` reads the resolved batch from the process dictionary via `Process.get(:batch_resolved)` and then unconditionally deletes it. That is sound only inside a task the library owns. On the `:backpressure_sync` and `:noproc` fallbacks `do_send/5` runs inline in the publishing caller\u0027s process, so if a resolver inside an outer `do_send/5` triggers another synchronous Ash notification, the inner call finds the outer run\u0027s value still under `:batch_resolved`, adopts it as its own result, and publishes it to the inner `topic`, a different subscription document with a different actor and tenant. It then deletes the key, so the outer run publishes nothing. The key is not namespaced by run, so records cannot be told apart. The fix saves, clears, and restores `:batch_resolved` around each run.\n\nThis issue affects ash_graphql: from 1.4.0 before 1.11.0."
            }
          ],
          "value": "Exposure of Data Element to Wrong Session vulnerability in ash-project ash_graphql can deliver one subscription\u0027s resolved records to a different subscriber\u0027s topic.\n\nAshGraphql.Subscription.Batcher.do_send/5 reads the resolved batch from the process dictionary via Process.get(:batch_resolved) and then unconditionally deletes it. That is sound only inside a task the library owns. On the :backpressure_sync and :noproc fallbacks do_send/5 runs inline in the publishing caller\u0027s process, so if a resolver inside an outer do_send/5 triggers another synchronous Ash notification, the inner call finds the outer run\u0027s value still under :batch_resolved, adopts it as its own result, and publishes it to the inner topic, a different subscription document with a different actor and tenant. It then deletes the key, so the outer run publishes nothing. The key is not namespaced by run, so records cannot be told apart. The fix saves, clears, and restores :batch_resolved around each run.\n\nThis issue affects ash_graphql: from 1.4.0 before 1.11.0."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-12",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-12 Choosing Message Identifier"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "HIGH",
            "attackRequirements": "PRESENT",
            "attackVector": "NETWORK",
            "baseScore": 2.3,
            "baseSeverity": "LOW",
            "privilegesRequired": "LOW",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "NONE",
            "vulnConfidentialityImpact": "LOW",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-488",
              "description": "CWE-488 Exposure of Data Element to Wrong Session",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-30T18:17:13.538Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/ash-project/ash_graphql/security/advisories/GHSA-wm4m-cjmc-5v8c"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-82367.html"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-82367"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/ash-project/ash_graphql/commit/b798ef5288664a0261990b19765558f168b718fb"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Re-entrant synchronous publish in AshGraphql subscription batcher delivers one subscriber\u0027s records to another\u0027s topic"
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-82367",
    "datePublished": "2026-08-30T18:17:13.538Z",
    "dateReserved": "2026-08-30T17:15:01.277Z",
    "dateUpdated": "2026-08-30T18:17:13.538Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…