Skip to content

fix: add missing encryption property to file metadata (#11648)#11783

Open
aakarsh12x wants to merge 6 commits intoappwrite:1.9.xfrom
aakarsh12x:fix/11648-file-encryption-metadata
Open

fix: add missing encryption property to file metadata (#11648)#11783
aakarsh12x wants to merge 6 commits intoappwrite:1.9.xfrom
aakarsh12x:fix/11648-file-encryption-metadata

Conversation

@aakarsh12x
Copy link
Copy Markdown

Summary

This adds the missing encryption property to persisted file metadata so the file document metadata stays aligned with whether the stored file content is encrypted.

References #11648.

What Was Missing

File uploads decide whether content is encrypted based on bucket configuration and file size, but that result was not being written back into the file's metadata payload.

That meant encrypted files could have metadata without an explicit encryption flag even though the file had been processed with encryption internally.

Root Cause

The upload flow stored content_type in metadata, but never persisted the resolved encryption state after the encryption decision was made.

Fix Applied

  • Persist metadata['encryption'] in the storage file upload flow using the same encryption condition already used by the file processor.
  • Add encryption: false to the other file-document creation paths that use the same metadata structure for generated or migrated files.

Consistency

After this change:

  • encrypted uploaded files persist metadata.encryption = true
  • non-encrypted files persist metadata.encryption = false
  • internally created file documents use the same metadata shape

I was not able to run the PHP test suite in this shell because php is not installed in the current environment.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 4, 2026

Greptile Summary

This PR fixes a gap in the storage file upload flow where the encryption flag was computed and applied to file bytes but never persisted into the file document's metadata array. It also includes an independent fix for validateDomainRestrictions to tolerate trailing-comma env variable values.

Key changes:

  • Storage/Http/Buckets/Files/Create.php: Sets $metadata['encryption'] at line 267 using the identical boolean condition ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) that gates actual OpenSSL encryption at line 314, so the stored flag is always consistent with what the upload flow does.
  • Functions/Workers/Screenshots.php: Adds 'encryption' => false to screenshot file documents — correct, since no encryption is applied (all OpenSSL fields are null).
  • Workers/Migrations.php: Adds 'encryption' => false to export-file documents — correct, since those files are also created without OpenSSL fields.
  • Modules/Proxy/Action.php: Adds an empty() guard when iterating domains from _APP_DOMAIN_FUNCTIONS, preventing exceptions when the env variable ends with a trailing comma.
  • tests/unit/Platform/Modules/Proxy/ActionTest.php: Adds a unit test verifying the trailing-comma guard does not throw.

Confidence Score: 5/5

Safe to merge — the fix correctly aligns the stored metadata flag with the actual encryption logic and all previously raised concerns have been addressed or were already discussed in prior review threads.

The metadata['encryption'] condition in Create.php is a verbatim copy of the condition used for actual encryption, ensuring full consistency. The false values in Screenshots.php and Migrations.php are correct given those files are created with null OpenSSL fields. The Proxy fix is independently safe and covered by a new test. No unaddressed P0 or P1 issues remain.

No files require special attention beyond the concerns already captured in prior review threads (storage device metadata side-effect, migration encrypted-source semantics).

Vulnerabilities

No security concerns identified. The encryption metadata flag is derived directly from the same bucket configuration attribute and file-size threshold already used to decide whether OpenSSL encryption is applied, so there is no path where the flag misrepresents the actual encryption state of a fully-uploaded file.

Important Files Changed

Filename Overview
src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Create.php Core fix: adds $metadata['encryption'] flag before upload using the same condition as the actual encryption step; accurately reflects the file's encryption state in the DB document across all four write paths.
src/Appwrite/Platform/Modules/Functions/Workers/Screenshots.php Adds 'encryption' => false to screenshot file metadata — correct since screenshot files are written directly with no OpenSSL fields.
src/Appwrite/Platform/Workers/Migrations.php Adds 'encryption' => false to export-file metadata; accurate because the document is created with openSSLVersion/Cipher/Tag/IV => null, confirming no encryption is applied.
src/Appwrite/Platform/Modules/Proxy/Action.php Independent fix: adds empty($functionsDomain) guard when iterating domain entries from _APP_DOMAIN_FUNCTIONS, preventing a crash on trailing-comma env values.
tests/unit/Platform/Modules/Proxy/ActionTest.php New unit test covering the empty-entry guard in validateDomainRestrictions; test passes a trailing-comma env value and asserts no exception is thrown.

Reviews (5): Last reviewed commit: "Merge branch 'appwrite:1.9.x' into fix/1..." | Re-trigger Greptile

}
}

$metadata['encryption'] = $bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER;
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.

P1 Encryption flag set before upload, passed to storage device

$metadata is passed directly into $deviceForFiles->upload() on the very next line. This means 'encryption' is now included in the metadata forwarded to the storage device (S3, GCS, local, etc.). Depending on the device adapter, this extra key may be written as an object-metadata header on every chunk. While the value is correct for the DB document (and all four write paths below correctly use $metadata), the side-effect on storage device metadata was not present before this change.

If the device adapters ignore unknown metadata keys this is safe, but if they forward them verbatim to the object store (as is common for S3-compatible adapters) you may end up with unwanted object metadata on stored files. Worth verifying in the device implementations before shipping.

Comment on lines 686 to 693
'openSSLTag' => null,
'openSSLIV' => null,
'search' => \implode(' ', [$fileId, $filename]),
'metadata' => ['content_type' => $mime]
'metadata' => [
'content_type' => $mime,
'encryption' => false,
]
]));
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.

P2 Hardcoded encryption => false may misrepresent migrated file state

The migration worker writes file documents for files imported from another Appwrite instance. If the source project had bucket encryption enabled, those files are already encrypted at rest. Persisting 'encryption' => false in the metadata of a file whose bytes are actually encrypted would cause consumers that rely on this flag to incorrectly believe the file is plain text.

It would be safer to derive the flag from the destination bucket's configuration (mirroring the logic in Create.php), or — if the migration always re-uploads raw bytes — to add a comment explaining why false is always correct here.

Comment on lines +43 to +44

$this->addToAssertionCount(1);
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.

P2 Prefer expectNotToPerformAssertions() over addToAssertionCount(1)

$this->addToAssertionCount(1) is a low-level bookkeeping call that was not designed to be used directly in test bodies — it just increments the counter without actually asserting anything. The idiomatic PHPUnit way to express "this block must not throw" is:

Suggested change
$this->addToAssertionCount(1);
$this->expectNotToPerformAssertions();
$action->validate('test.functions.example.com', ['hostnames' => []]);

Alternatively, $this->assertTrue(true) is widely understood by teams that don't yet target PHPUnit 10+.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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.

2 participants