GHSA-66R2-5GWJ-GXM2
Vulnerability from github – Published: 2026-09-04 20:50 – Updated: 2026-09-04 20:50A PERMISSIONS ... WHERE clause is evaluated with permission enforcement disabled, so it can't recurse into its own checks. But the clause could also contain data-modifying statements, and these ran with enforcement still off — so evaluating a permission check could write to tables the caller cannot write.
For example:
DEFINE TABLE post PERMISSIONS FOR update
WHERE (CREATE log SET at = time::now()) OR true;
Any user allowed to update a post now also creates a log record, even with no permission on log. The clause is evaluated once per matched record, so one statement can cause several writes.
Impact
Only databases with a PERMISSIONS clause that contains a write are affected; FULL, NONE, and read-only clauses are not.
What an attacker can do:
- With permission to perform the guarded operation (a low-privileged or record user is enough), write to tables in their own database that their permissions would otherwise forbid, by triggering an operation the clause guards.
- Cause several writes from a single statement — the clause is evaluated once per matched record.
- Trigger unintended events, cascades, or data corruption on those tables.
What it can't do:
- Escape the caller's own namespace and database — a permission clause cannot switch namespace or database.
- Perform root- or namespace-level actions such as creating users; the caller's role still applies.
- Read hidden data — this is an integrity issue, not disclosure.
Patches
Permission clauses must now be read-only: defining or importing one that contains a write is rejected, and any write attempted while a clause is evaluated is blocked at runtime, including writes reached through a called function. Read-only clauses are unaffected.
- Versions 3.2.0 and later are not affected by this issue.
Workarounds
Users unable to patch should consider the following workarounds:
- Review your
PERMISSIONSclauses and remove any containingCREATE,UPDATE,DELETE,RELATE,INSERT, orUPSERT. - Limit who can define schema and vet imported data — such a clause must be defined before it can be triggered.
Resources
- DEFINE TABLE … PERMISSIONS
- DEFINE FIELD
fix(core): reject writes in PERMISSIONS clauses and block writes during permission evaluation(included in SurrealDB 3.2.0)
Acknowledgements
Thank you to sondt99 for reporting this issue.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "surrealdb-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-63733"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-04T20:50:40Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "A `PERMISSIONS ... WHERE` clause is evaluated with permission enforcement disabled, so it can\u0027t recurse into its own checks. But the clause could also contain data-modifying statements, and these ran with enforcement still off \u2014 so evaluating a permission check could write to tables the caller cannot write.\n\nFor example:\n\n```surql\nDEFINE TABLE post PERMISSIONS FOR update\n WHERE (CREATE log SET at = time::now()) OR true;\n```\n\nAny user allowed to update a `post` now also creates a `log` record, even with no permission on `log`. The clause is evaluated once per matched record, so one statement can cause several writes.\n\n### Impact\n\nOnly databases with a `PERMISSIONS` clause that contains a write are affected; `FULL`, `NONE`, and read-only clauses are not.\n\nWhat an attacker **can** do:\n\n- With permission to perform the guarded operation (a low-privileged or record user is enough), write to tables in their own database that their permissions would otherwise forbid, by triggering an operation the clause guards.\n- Cause several writes from a single statement \u2014 the clause is evaluated once per matched record.\n- Trigger unintended events, cascades, or data corruption on those tables.\n\nWhat it **can\u0027t** do:\n\n- Escape the caller\u0027s own namespace and database \u2014 a permission clause cannot switch namespace or database.\n- Perform root- or namespace-level actions such as creating users; the caller\u0027s role still applies.\n- Read hidden data \u2014 this is an integrity issue, not disclosure.\n\n### Patches\n\nPermission clauses must now be read-only: defining or importing one that contains a write is rejected, and any write attempted while a clause is evaluated is blocked at runtime, including writes reached through a called function. Read-only clauses are unaffected.\n\n- Versions 3.2.0 and later are not affected by this issue.\n\n### Workarounds\n\nUsers unable to patch should consider the following workarounds:\n\n- Review your `PERMISSIONS` clauses and remove any containing `CREATE`, `UPDATE`, `DELETE`, `RELATE`, `INSERT`, or `UPSERT`.\n- Limit who can define schema and vet imported data \u2014 such a clause must be defined before it can be triggered.\n\n### Resources\n\n- [DEFINE TABLE \u2026 PERMISSIONS](https://surrealdb.com/docs/surrealql/statements/define/table)\n- [DEFINE FIELD](https://surrealdb.com/docs/surrealql/statements/define/field)\n- `fix(core): reject writes in PERMISSIONS clauses and block writes during permission evaluation` (included in SurrealDB 3.2.0)\n\n### Acknowledgements\n\nThank you to [sondt99](https://github.com/sondt99) for reporting this issue.",
"id": "GHSA-66r2-5gwj-gxm2",
"modified": "2026-09-04T20:50:40Z",
"published": "2026-09-04T20:50:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/security/advisories/GHSA-66r2-5gwj-gxm2"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-63733"
},
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/commit/1e4c3d743e1591f14f340cb627e56d98b6bd7fd7"
},
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/commit/afea699dfb3c8f274ab36861f8a95f5e98d82f1b"
},
{
"type": "PACKAGE",
"url": "https://github.com/surrealdb/surrealdb"
},
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/releases/tag/v3.2.0"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/surrealdb-before-permissions-bypass-via-permissions-clause"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "SurrealDB: Writes in a PERMISSIONS clause bypass table permissions"
}
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.
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.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.