Skip to content

[Storage] Canonicalize backslashes in blob names when generating a blob SAS - #48697

Open
om singhal (Om-singhaI) wants to merge 1 commit into
Azure:mainfrom
Om-singhaI:fix/blob-sas-backslash-canonical-resource
Open

[Storage] Canonicalize backslashes in blob names when generating a blob SAS#48697
om singhal (Om-singhaI) wants to merge 1 commit into
Azure:mainfrom
Om-singhaI:fix/blob-sas-backslash-canonical-resource

Conversation

@Om-singhaI

Copy link
Copy Markdown

Description

Fixes #48690

generate_blob_sas inserted the blob name verbatim into the canonicalized resource of the string to sign (resource_path = container_name + "/" + blob_name in sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py). The Azure Storage service canonicalizes a backslash (\) in a blob name to a forward slash (/) before it validates the signature, so a SAS generated for any blob name containing a backslash never matched and the service rejected it with a 403. The reporter reproduced this against Azurite.

This change normalizes backslashes to forward slashes in the blob name when building the signed resource path, so the computed signature matches what the service computes. It mirrors the sibling SDKs:

  • azure-sdk-for-go, sdk/storage/azblob/sas/service.go, getCanonicalName (lines 336 to 345): appends strings.ReplaceAll(blobName, "\\", "/") at line 341 and leaves directoryName untouched.
  • azure-sdk-for-net, sdk/storage/Azure.Storage.Blobs/src/Sas/BlobSasBuilder.cs, GetCanonicalName (lines 591 to 594): blobName.Replace("\\", "/").

Scope follows the Go implementation exactly: only the blob name is normalized, and only when is_directory is not set. Directory names are signed as given. The container name is not touched. The blob name used in the request URL is not changed (it is still percent encoded as %5C), only the signed resource line is. Since azure-storage-file-datalake wraps generate_blob_sas, the fix propagates there as well.

A note on scope: the issue currently carries the default question label, but the behavior is a defect. Non HNS accounts canonicalize a backslash the same way, which is why the Go and .NET SDKs apply this normalization unconditionally for blob names.

Before (string to sign, canonicalized resource line, for blob_name="dir\\file"):

/blob/acct/testc/dir\file

After:

/blob/acct/testc/dir/file

Testing

Added sdk/storage/azure-storage-blob/tests/test_shared_access_signature.py, a standalone unit test module that uses the existing sts_hook parameter of generate_blob_sas to capture the string to sign. It asserts that:

  • the canonicalized resource line contains / in place of the backslash, the token's sr is still b, the token is identical to the one generated for the equivalent forward slash name, and the URL path built by BlobClient still carries the original %5C encoded name;
  • with is_directory=True the directory name is signed as given and sr is d.

The new test fails on the parent commit (1 failed, 1 passed) and passes with this change (2 passed). Ran black with eng/black-pyproject.toml on the changed files (no changes) and pylint with the repo rc files (no new findings attributable to this change).

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

…a blob SAS

The service treats a backslash in a blob name as a forward slash when it validates a SAS signature, but generate_blob_sas signed the blob name verbatim. Any SAS generated for a blob name containing a backslash was therefore rejected with a 403.

Normalize backslashes to forward slashes when building the signed resource path, matching the Go and .NET SDKs. Directory names are signed as given, as in the Go SDK. The blob name used in the request URL is unchanged.

Adds a standalone unit test that checks the canonicalized resource line through the existing sts_hook parameter, and a CHANGELOG entry.

Fixes Azure#48690
Copilot AI balanced review requested due to automatic review settings August 22, 2026 20:10
@github-actions github-actions Bot added Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. Storage Storage Service (Queues, Blobs, Files) labels Aug 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution om singhal (@Om-singhaI)! We will review the pull request and get back to you soon.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
7 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI 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.

Pull request overview

Fixes blob SAS authentication for blob names containing backslashes by matching Azure Storage’s canonicalization behavior.

Changes:

  • Normalizes backslashes only for non-directory SAS resource paths.
  • Adds focused tests for signatures, directory behavior, and URL encoding.
  • Documents the fix in the changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
_shared_access_signature.py Canonicalizes blob names during SAS signing.
test_shared_access_signature.py Tests blob and directory SAS behavior.
CHANGELOG.md Records the bug fix.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

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

Labels

Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. Storage Storage Service (Queues, Blobs, Files)

Projects

None yet

2 participants