Skip to content

Fix corrupted destination filename in Crop/Scale when source is a signed URL#1272

Merged
claudiamurialdo merged 3 commits into
masterfrom
fix/crop-scale-signed-url-filename
Apr 22, 2026
Merged

Fix corrupted destination filename in Crop/Scale when source is a signed URL#1272
claudiamurialdo merged 3 commits into
masterfrom
fix/crop-scale-signed-url-filename

Conversation

@claudiamurialdo
Copy link
Copy Markdown
Collaborator

When an image loaded from an external storage provider (e.g. S3 with pre-signed URLs) was passed to Crop/Scale/Resize/Save, the destination blob name was derived from the full URL — including the query string — producing names like image.png%3FX-Amz-Expires%3D...%26X-Amz-Signature%3D.... The URL-to-filename normalization was gated on the absence of an external provider, which is exactly the scenario where signed URLs appear.

Apply the normalization unconditionally for http/https inputs.

Issue:208429

…ned URL

When an image loaded from an external storage provider (e.g. S3 with
pre-signed URLs) was passed to Crop/Scale/Resize/Save, the destination
blob name was derived from the full URL — including the query string —
producing names like `image.png%3FX-Amz-Expires%3D...%26X-Amz-Signature%3D...`.
The URL-to-filename normalization was gated on the absence of an external
provider, which is exactly the scenario where signed URLs appear.

Apply the normalization unconditionally for http/https inputs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claudiamurialdo claudiamurialdo temporarily deployed to kafka-integration-tests April 21, 2026 17:53 — with GitHub Actions Inactive
@claudiamurialdo claudiamurialdo had a problem deploying to external-storage-tests April 21, 2026 17:53 — with GitHub Actions Failure
@genexusbot
Copy link
Copy Markdown
Collaborator

Cherry pick to beta success

The ImageUtilTest file is shared between DotNetUnitTest (net462) and
DotNetCoreUnitTest (net10). Use the same #if NETCORE / System.Drawing
pattern already in GXUtilsCommon so the new test compiles on both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claudiamurialdo claudiamurialdo temporarily deployed to kafka-integration-tests April 21, 2026 18:08 — with GitHub Actions Inactive
@claudiamurialdo claudiamurialdo temporarily deployed to external-storage-tests April 21, 2026 18:08 — with GitHub Actions Inactive
@genexusbot
Copy link
Copy Markdown
Collaborator

Cherry pick to beta success

The previous assertion compared the resolved malicious path against
Preferences.getBLOB_PATH() directly. When a prior test in the same
process sets GxContext.IsHttpContext = true (via GxNetCoreStartup), the
cached blobPath gets rooted at Directory.GetParent(GetStartupDirectory())
= bin/Release, while ResolveUri itself can still reresolve paths against
the current working directory (bin/Release/net10.0), making the StartsWith
check fail even when no real traversal occurred.

Derive the comparison base from ResolveUri of a known-safe filename, so
both sides go through the same code path and share any environment-
dependent rooting. The security invariant checked is unchanged: resolved
malicious inputs must stay inside the blob/multimedia directory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claudiamurialdo claudiamurialdo temporarily deployed to kafka-integration-tests April 21, 2026 18:39 — with GitHub Actions Inactive
@claudiamurialdo claudiamurialdo temporarily deployed to external-storage-tests April 21, 2026 18:39 — with GitHub Actions Inactive
@genexusbot
Copy link
Copy Markdown
Collaborator

Cherry pick to beta success

@claudiamurialdo claudiamurialdo merged commit 98fa0ae into master Apr 22, 2026
10 checks passed
@claudiamurialdo claudiamurialdo deleted the fix/crop-scale-signed-url-filename branch April 22, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants