CVE-2026-81318 (GCVE-0-2026-81318)
Vulnerability from cvelistv5 – Published: 2026-08-30 11:56 – Updated: 2026-08-30 11:56
VLAI
EPSS
VEX
Title
Distinct-query aggregate drops the tenant schema prefix, leaking across tenants in AshSql
Summary
Incorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant's rows.
When an aggregate is computed over a distinct query, AshSql.AggregateQuery.add_single_aggs/5 rebuilds the outer query from query.from.source alone, which is only the {table, schema} tuple and does not carry query.prefix or query.from.prefix. For strategy(:context) multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo's default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant's rows. The neighbouring limit and exists branches instead wrap the query with subquery/1, which preserves the prefix.
This issue affects ash_sql: from 0.1.0 before 0.7.1.
Severity
CWE
- CWE-863 - Incorrect Authorization
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_sql/security/a… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-81318.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-81318 | related |
| https://github.com/ash-project/ash_sql/commit/3d9… | patch |
Impacted products
2 products
| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| ash-project | ash_sql |
Affected:
0.1.0 , < 0.7.1
(semver)
cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:* |
||
| ash-project | ash_sql |
Affected:
dd092ed273dec7bd2194352f24a39229fc8ae68b , < 3d95478cc9e1d5bfaf6144fe9b9793f29e5ab889
(git)
cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:* |
{
"containers": {
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshSql.AggregateQuery\u0027"
],
"packageName": "ash_sql",
"packageURL": "pkg:hex/ash_sql",
"product": "ash_sql",
"programFiles": [
"lib/aggregate_query.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshSql.AggregateQuery\u0027:add_single_aggs/5"
}
],
"repo": "https://github.com/ash-project/ash_sql",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.7.1",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshSql.AggregateQuery\u0027"
],
"packageName": "ash-project/ash_sql",
"packageURL": "pkg:github/ash-project/ash_sql",
"product": "ash_sql",
"programFiles": [
"lib/aggregate_query.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshSql.AggregateQuery\u0027:add_single_aggs/5"
}
],
"repo": "https://github.com/ash-project/ash_sql",
"vendor": "ash-project",
"versions": [
{
"lessThan": "3d95478cc9e1d5bfaf6144fe9b9793f29e5ab889",
"status": "affected",
"version": "dd092ed273dec7bd2194352f24a39229fc8ae68b",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn application must use AshPostgres schema-based (\u003ccode\u003estrategy(:context)\u003c/code\u003e) multitenancy and compute an aggregate over a \u003ccode\u003edistinct\u003c/code\u003e query (for example an aggregate whose query filters across a to-many relationship).\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An application must use AshPostgres schema-based (`strategy(:context)`) multitenancy and compute an aggregate over a `distinct` query (for example an aggregate whose query filters across a to-many relationship)."
}
],
"value": "An application must use AshPostgres schema-based (strategy(:context)) multitenancy and compute an aggregate over a distinct query (for example an aggregate whose query filters across a to-many relationship)."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.7.1",
"versionStartIncluding": "0.1.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\u003eIncorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant\u0027s rows.\u003c/p\u003e\n\u003cp\u003eWhen an aggregate is computed over a \u003ccode\u003edistinct\u003c/code\u003e query, \u003ccode\u003eAshSql.AggregateQuery.add_single_aggs/5\u003c/code\u003e rebuilds the outer query from \u003ccode\u003equery.from.source\u003c/code\u003e alone, which is only the \u003ccode\u003e{table, schema}\u003c/code\u003e tuple and does not carry \u003ccode\u003equery.prefix\u003c/code\u003e or \u003ccode\u003equery.from.prefix\u003c/code\u003e. For \u003ccode\u003estrategy(:context)\u003c/code\u003e multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo\u0027s default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant\u0027s rows. The neighbouring limit and exists branches instead wrap the query with \u003ccode\u003esubquery/1\u003c/code\u003e, which preserves the prefix.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_sql: from 0.1.0 before 0.7.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Incorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant\u0027s rows.\n\nWhen an aggregate is computed over a `distinct` query, `AshSql.AggregateQuery.add_single_aggs/5` rebuilds the outer query from `query.from.source` alone, which is only the `{table, schema}` tuple and does not carry `query.prefix` or `query.from.prefix`. For `strategy(:context)` multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo\u0027s default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant\u0027s rows. The neighbouring limit and exists branches instead wrap the query with `subquery/1`, which preserves the prefix.\n\nThis issue affects ash_sql: from 0.1.0 before 0.7.1."
}
],
"value": "Incorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant\u0027s rows.\n\nWhen an aggregate is computed over a distinct query, AshSql.AggregateQuery.add_single_aggs/5 rebuilds the outer query from query.from.source alone, which is only the {table, schema} tuple and does not carry query.prefix or query.from.prefix. For strategy(:context) multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo\u0027s default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant\u0027s rows. The neighbouring limit and exists branches instead wrap the query with subquery/1, which preserves the prefix.\n\nThis issue affects ash_sql: from 0.1.0 before 0.7.1."
}
],
"impacts": [
{
"capecId": "CAPEC-1",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 2.1,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/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-863",
"description": "CWE-863 Incorrect Authorization",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-08-30T11:56:52.921Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_sql/security/advisories/GHSA-ww8j-58rc-f8h3"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-81318.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-81318"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_sql/commit/3d95478cc9e1d5bfaf6144fe9b9793f29e5ab889"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Distinct-query aggregate drops the tenant schema prefix, leaking across tenants in AshSql"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-81318",
"datePublished": "2026-08-30T11:56:52.921Z",
"dateReserved": "2026-08-30T02:30:02.111Z",
"dateUpdated": "2026-08-30T11:56:52.921Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"nvd": "{\"cve\":{\"id\":\"CVE-2026-81318\",\"sourceIdentifier\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"published\":\"2026-08-30T12:17:19.030\",\"lastModified\":\"2026-08-30T12:17:19.030\",\"vulnStatus\":\"Received\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"Incorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant\u0027s rows.\\n\\nWhen an aggregate is computed over a distinct query, AshSql.AggregateQuery.add_single_aggs/5 rebuilds the outer query from query.from.source alone, which is only the {table, schema} tuple and does not carry query.prefix or query.from.prefix. For strategy(:context) multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo\u0027s default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant\u0027s rows. The neighbouring limit and exists branches instead wrap the query with subquery/1, which preserves the prefix.\\n\\nThis issue affects ash_sql: from 0.1.0 before 0.7.1.\"}],\"affected\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"affectedData\":[{\"vendor\":\"ash-project\",\"product\":\"ash_sql\",\"defaultStatus\":\"unaffected\",\"collectionURL\":\"https://repo.hex.pm\",\"packageName\":\"ash_sql\",\"cpes\":[\"cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:*\"],\"modules\":[\"\u0027Elixir.AshSql.AggregateQuery\u0027\"],\"programFiles\":[\"lib/aggregate_query.ex\"],\"programRoutines\":[{\"name\":\"\u0027Elixir.AshSql.AggregateQuery\u0027:add_single_aggs/5\"}],\"repo\":\"https://github.com/ash-project/ash_sql\",\"packageURL\":\"pkg:hex/ash_sql\",\"versions\":[{\"version\":\"0.1.0\",\"lessThan\":\"0.7.1\",\"versionType\":\"semver\",\"status\":\"affected\"}]},{\"vendor\":\"ash-project\",\"product\":\"ash_sql\",\"defaultStatus\":\"unaffected\",\"collectionURL\":\"https://github.com\",\"packageName\":\"ash-project/ash_sql\",\"cpes\":[\"cpe:2.3:a:ash-project:ash_sql:*:*:*:*:*:*:*:*\"],\"modules\":[\"\u0027Elixir.AshSql.AggregateQuery\u0027\"],\"programFiles\":[\"lib/aggregate_query.ex\"],\"programRoutines\":[{\"name\":\"\u0027Elixir.AshSql.AggregateQuery\u0027:add_single_aggs/5\"}],\"repo\":\"https://github.com/ash-project/ash_sql\",\"packageURL\":\"pkg:github/ash-project/ash_sql\",\"versions\":[{\"version\":\"dd092ed273dec7bd2194352f24a39229fc8ae68b\",\"lessThan\":\"3d95478cc9e1d5bfaf6144fe9b9793f29e5ab889\",\"versionType\":\"git\",\"status\":\"affected\"}]}]}],\"metrics\":{\"cvssMetricV40\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"type\":\"Secondary\",\"cvssData\":{\"version\":\"4.0\",\"vectorString\":\"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/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\",\"baseScore\":2.1,\"baseSeverity\":\"LOW\",\"attackVector\":\"LOCAL\",\"attackComplexity\":\"LOW\",\"attackRequirements\":\"PRESENT\",\"privilegesRequired\":\"NONE\",\"userInteraction\":\"NONE\",\"vulnConfidentialityImpact\":\"LOW\",\"vulnIntegrityImpact\":\"NONE\",\"vulnAvailabilityImpact\":\"NONE\",\"subConfidentialityImpact\":\"NONE\",\"subIntegrityImpact\":\"NONE\",\"subAvailabilityImpact\":\"NONE\",\"exploitMaturity\":\"NOT_DEFINED\",\"confidentialityRequirement\":\"NOT_DEFINED\",\"integrityRequirement\":\"NOT_DEFINED\",\"availabilityRequirement\":\"NOT_DEFINED\",\"modifiedAttackVector\":\"NOT_DEFINED\",\"modifiedAttackComplexity\":\"NOT_DEFINED\",\"modifiedAttackRequirements\":\"NOT_DEFINED\",\"modifiedPrivilegesRequired\":\"NOT_DEFINED\",\"modifiedUserInteraction\":\"NOT_DEFINED\",\"modifiedVulnConfidentialityImpact\":\"NOT_DEFINED\",\"modifiedVulnIntegrityImpact\":\"NOT_DEFINED\",\"modifiedVulnAvailabilityImpact\":\"NOT_DEFINED\",\"modifiedSubConfidentialityImpact\":\"NOT_DEFINED\",\"modifiedSubIntegrityImpact\":\"NOT_DEFINED\",\"modifiedSubAvailabilityImpact\":\"NOT_DEFINED\",\"Safety\":\"NOT_DEFINED\",\"Automatable\":\"NOT_DEFINED\",\"Recovery\":\"NOT_DEFINED\",\"valueDensity\":\"NOT_DEFINED\",\"vulnerabilityResponseEffort\":\"NOT_DEFINED\",\"providerUrgency\":\"NOT_DEFINED\"}}]},\"weaknesses\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"type\":\"Secondary\",\"description\":[{\"lang\":\"en\",\"value\":\"CWE-863\"}]}],\"references\":[{\"url\":\"https://cna.erlef.org/cves/CVE-2026-81318.html\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://github.com/ash-project/ash_sql/commit/3d95478cc9e1d5bfaf6144fe9b9793f29e5ab889\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://github.com/ash-project/ash_sql/security/advisories/GHSA-ww8j-58rc-f8h3\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://osv.dev/vulnerability/EEF-CVE-2026-81318\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"}]}}"
}
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Loading…
Loading…