Visitar URL original
fix(databases): block string operators on encrypted attributes in parseOperators by okxint · Pull Request #14250 · appwrite/appwrite · GitHub
Skip to content

fix(databases): block string operators on encrypted attributes in parseOperators - #14250

Open
okxint wants to merge 1 commit into
appwrite:mainfrom
okxint:fix/block-operators-on-encrypted-attributes
Open

okxint wants to merge 1 commit into
appwrite:mainfrom
okxint:fix/block-operators-on-encrypted-attributes

Conversation

@okxint

@okxint okxint commented Oct 8, 2026

Copy link
Copy Markdown

Fixes #14218

parseOperators already skips relationship attributes via a $relationshipKeys lookup before processing operators. There was no equivalent guard for encrypted attributes.

When a stringReplace (or any string operator) arrives for a column marked encrypt: true, the operator passes through and Postgres runs REPLACE(COALESCE(col, ''), ...) directly on the stored ciphertext envelope — a JSON blob with data, method, iv, and tag keys. Replacing common hex characters in that envelope corrupts its structure; decryption then returns false and the value is unrecoverable.

The encrypt flag is already available on every attribute Document at the time parseOperators runs (set in app/init/database/filters.php).

Fix: Collect encrypted attribute keys in the same loop that already collects relationship keys, then throw GENERAL_ARGUMENT_INVALID before any operator is parsed for those attributes — mirroring the existing relationship-key guard exactly.

@hansi-codes

hansi-codes Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🟡 Tier B · Needs changes before merging

The new guard blocks normal updates to encrypted attributes, not only operator updates.

This change adds encrypted-attribute detection to database operator parsing and rejects operators targeting those fields. The check is added alongside the existing relationship-attribute handling in the shared Databases action.

Verdict New comments Fixed Still open
🛑 Changes requested 1 0 0
Finding Where
🟠 Only reject encrypted attributes when the value is an operator src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php:116
Fix with agent prompt
### Issue 1
src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php:116-117
**Only reject encrypted attributes when the value is an operator**

`parseOperators` also receives ordinary write payloads from Documents/Update, Upsert, and Bulk/Update, so this unconditional key check rejects a normal plaintext assignment to any encrypted attribute. Please limit the rejection to values that actually encode a recognized operator; otherwise existing encrypted fields become unwritable through these APIs.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
📂 Walkthrough · 1
File Change
src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php Collects encrypted attribute keys and checks them during operator parsing.

Reviewed ef2af05 · Details · Comment @hansi-codes review to re-run, or mention @hansi-codes with a question.

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Tier B · 1 blocking finding to address. Summary

Comment on lines +116 to +117
if (isset($encryptedKeys[$key])) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Attribute "' . $key . '" is encrypted and does not support string operators.');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only reject encrypted attributes when the value is an operator

parseOperators also receives ordinary write payloads from Documents/Update, Upsert, and Bulk/Update, so this unconditional key check rejects a normal plaintext assignment to any encrypted attribute. Please limit the rejection to values that actually encode a recognized operator; otherwise existing encrypted fields become unwritable through these APIs.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Appwrite/Platform/Modules/Databases/Http/Databases/Action.php
Line: 116-117

Comment:
**Only reject encrypted attributes when the value is an operator**

`parseOperators` also receives ordinary write payloads from Documents/Update, Upsert, and Bulk/Update, so this unconditional key check rejects a normal plaintext assignment to any encrypted attribute. Please limit the rejection to values that actually encode a recognized operator; otherwise existing encrypted fields become unwritable through these APIs.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

🟠 Major · bug · Reply if this doesn't apply.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: stringReplace on an encrypted column destroys the value

1 participant