Skip to content

[Storage] Detect region reorder during Blob decryption - #48559

Open
Jacob Lauzon (jalauzon-msft) wants to merge 6 commits into
Azure:mainfrom
jalauzon-msft:cse-reorder
Open

[Storage] Detect region reorder during Blob decryption#48559
Jacob Lauzon (jalauzon-msft) wants to merge 6 commits into
Azure:mainfrom
jalauzon-msft:cse-reorder

Conversation

@jalauzon-msft

Copy link
Copy Markdown
Member

No description provided.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 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

Strengthens Blob client-side encryption v2 by detecting reordered authenticated regions during decryption.

Changes:

  • Parses response content ranges to derive expected nonce counters.
  • Validates each region nonce, with an environment-variable recovery bypass.
  • Adds synchronous and asynchronous live tests for reordered regions.

Reviewed changes

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

File Description
_encryption.py Adds content-range parsing and nonce-order validation.
test_blob_encryption_v2.py Adds synchronous reorder coverage.
test_blob_encryption_v2_async.py Adds asynchronous reorder coverage.

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

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/test_blob_encryption_v2.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/test_blob_encryption_v2_async.py Outdated
Copilot AI review requested due to automatic review settings August 12, 2026 23:05

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py Outdated
Copilot AI review requested due to automatic review settings August 12, 2026 23:46

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py:1005

  • Please document both the new default rejection of reordered CSE v2 regions and this recovery-only environment variable in the package's Unreleased CHANGELOG entry. Without release documentation, existing blobs that previously decrypted can begin failing after upgrade, while users have no public guidance about the intentionally provided recovery path or its integrity tradeoff.
        # Bypass nonce validation via an environment variable for data-recovery scenarios
        # where regions were reordered. Not recommended: it can allow tampered data through.
        validate_nonce = not os.environ.get("AZURE_STORAGE_CSE_V2_ALLOW_MISORDERED_AUTH_REGIONS")

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py Outdated
Copilot AI review requested due to automatic review settings August 13, 2026 00:01

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

sdk/storage/azure-storage-blob/tests/test_blob_encryption_v2.py:463

  • The recovery branch introduced by this change is not covered: this test verifies only the default rejection path. Because the environment variable deliberately bypasses a security validation, exercise it here and assert that the reordered plaintext can be recovered.
        # Act / Assert -- a region's nonce no longer matches its position
        with pytest.raises(HttpResponseError) as e:
            blob.download_blob().readall()

        assert "Decryption failed." in str(e.value)

sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py:1014

  • This data-recovery switch is currently discoverable only by reading private implementation code, while the unreleased CHANGELOG section has no entry for either the new decryption failure or its opt-out. Add a Bugs Fixed note documenting the behavior and the exact environment variable so affected users can recover previously reordered blobs.
        # Bypass nonce validation via an environment variable for data-recovery scenarios
        # where regions were reordered. Not recommended: it can allow tampered data through.
        validate_nonce = os.environ.get(
            "AZURE_STORAGE_CSE_V2_ALLOW_MISORDERED_AUTH_REGIONS", ""
        ).strip().lower() not in ("true", "1")

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py Outdated
Copilot AI review requested due to automatic review settings August 13, 2026 00:44

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

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

Suppressed comments (2)

sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py:1025

  • These candidate sets are not disjoint, so selecting from their union independently for every region does not reliably detect reordering. For example, Java region 256 has nonce 000000000000010000000000, which is also the .NET candidate for expected region 65535 (65536 little-endian after the four-byte prefix). A ranged read after moving that block in a valid 256-GiB Java blob would therefore authenticate and return plaintext from the wrong position. Bind a blob/download to one nonce encoding (and enforce it consistently across regions) rather than accepting the per-region union; the compatibility mechanism may require a protocol-level decision.
            if validate_nonce:
                if nonce not in _region_nonce_candidates(nonce_counter, nonce_length):
                    raise ValueError("The encryption metadata is not valid and may have been modified.")

sdk/storage/azure-storage-blob/azure/storage/blob/_encryption.py:1011

  • The new recovery switch is not exercised by either reordered-region test; both only cover default rejection. Add coverage that sets this environment variable, confirms reordered authenticated regions can be recovered, and restores the environment afterward. This security-sensitive escape hatch otherwise could regress or have its boolean semantics inverted unnoticed.
        validate_nonce = os.environ.get(
            "AZURE_STORAGE_CSE_V2_ALLOW_MISORDERED_AUTH_REGIONS", ""
        ).strip().lower() not in ("true", "1")

@github-actions

This comment has been minimized.

Copilot AI review requested due to automatic review settings August 13, 2026 18:37

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

"AZURE_STORAGE_CSE_V2_ALLOW_MISORDERED_AUTH_REGIONS", ""
).strip().lower() not in ("true", "1")

candidate_encodings = _region_nonce_encodings(nonce_length)
@github-actions

Copy link
Copy Markdown
Contributor
[Pilot] PR Pipeline Failure Analysis

A CI pipeline failed on this pull request. Here is an automated analysis of what went wrong and how to get the build green.

What failed

The python - pullrequest pipeline (Build 6699760) failed on the black formatting check for azure-storage-blob. Two files have formatting issues that black would reformat:

  • azure/storage/blob/_encryption.py — a dict comprehension was written across multiple lines in a style black wants collapsed to one line.
  • tests/test_blob_encryption_v2.py — a list comprehension was similarly split across lines in a style black wants collapsed.

Recommended next steps

  • Run azpysdk black . from sdk/storage/azure-storage-blob/ to auto-fix the formatting issues.
  • Commit and push the reformatted files.
  • See the CI troubleshooting guide: https://aka.ms/ci-fix
  • Push new commits to address the failures; this comment updates automatically on the next failing run.
Raw pipeline analysis (azsdk ci analyze)
Build: 6699760 Project: public
PipelineUrl: https://dev.azure.com/azure-sdk/public/_build/results?buildId=6699760

Failed Task: black :: azure-storage-blob

[azure-storage-blob :: black] The package azure-storage-blob has black formatting issues.
Run `azpysdk black .` locally from the package root to reformat.

Black diff:
--- azure/storage/blob/_encryption.py
@@ -1023,13 +1023,11 @@
     if validate_nonce:
         candidate_encodings = {
-            name: encode
-            for name, encode in candidate_encodings.items()
-            if encode(nonce_counter) == nonce
+            name: encode for name, encode in candidate_encodings.items() if encode(nonce_counter) == nonce
         }

--- tests/test_blob_encryption_v2.py
@@ -543,12 +543,11 @@
     encrypted_regions = [
-        java_nonce(i) + aesgcm.encrypt(java_nonce(i), region, None)
-        for i, region in enumerate(plaintext_regions)
+        java_nonce(i) + aesgcm.encrypt(java_nonce(i), region, None) for i, region in enumerate(plaintext_regions)
     ]

Summary: 2 files would be reformatted, 204 files would be left unchanged.
black check completed with exit code 1

Failing checks:
  python - pullrequest [FAILURE] https://dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_build/results?buildId=6699760
  python - pullrequest (Build Analyze) [FAILURE] https://dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_build/results?buildId=6699760&view=logs&jobId=b70e5e73-bbb6-5567-0939-8415943fadb9

Copilot detected the failing pipeline and generated the analysis above. To have it attempt a fix automatically, reply with `@copilot please fix the failing pipeline on this PR`.

Generated by Pipeline Analysis - Next Steps · 26.5 AIC · ⌖ 6.27 AIC · ⊞ 6.6K ·

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

Labels

Storage Storage Service (Queues, Blobs, Files)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants