Repository navigation
Reject content writes addressed to a blob snapshot URL - #2895
Open
compiler-segfault (compiler-segfault) wants to merge 1 commit into
Open
compiler-segfault (compiler-segfault) wants to merge 1 commit into
compiler-segfault (compiler-segfault) wants to merge 1 commit into
Conversation
compiler-segfault (compiler-segfault)
force-pushed
the
fix/snapshot-write-target
branch
from
November 8, 2026 12:31
f1d49bf to
14c750a
Compare
The snapshot query parameter is only read by the read, delete, and lease
handlers, so a content write that named a snapshot was treated as an ordinary
write to the base blob: a Put Blob to a snapshot URL returned 201 and replaced
the live blob.
Snapshots are immutable, so reject these requests with 400 InvalidOperation
("Invalid operation against a blob snapshot.") before any content is persisted.
Covers Put Blob, Put Blob From URL, Put Block, Put Block From URL, Put Block
List, Create Page Blob, Put Page, Clear Page, Resize Page Blob, Set Page Blob
Sequence Number, Create Append Blob, Append Block, Append Block Seal, and both
copy operations.
Fixes Azure#2854
compiler-segfault (compiler-segfault)
force-pushed
the
fix/snapshot-write-target
branch
from
November 8, 2026 12:33
14c750a to
1200119
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A content write whose request URL names a snapshot is applied to the base blob
instead of being rejected, so the emulator silently modifies the live blob that
the caller believes they are only reading.
Reproduction from #2854, on
main(716539c):PUT /container/bwith body1PUT /container/b?comp=snapshot-> snapshotSPUT /container/b?snapshot=Swith body2Before this change step 3 returns
201andGET /container/breturns2while the snapshot still returns
1. Expected: the write is rejected and thebase blob keeps returning
1.Root cause
?snapshot=is read by the download/properties/block-list paths, by delete (todelete one snapshot), and by the lease handlers. No content-write handler reads
it, so the request falls through to the base blob.
Fix
Added
validateWriteTargetIsNotSnapshot()insrc/blob/utils/utils.tsandcall it at the entry of every content-writing handler. It returns
400 InvalidOperationwith the Azure messageInvalid operation against a blob snapshot.when the request URL carries a non-emptysnapshotparameter, beforeany content or extent is written.
Operations covered:
Put Blob,Put Blob From URL,Put Block,Put Block From URL,Put Block List,Create Page Blob,Put Page,Clear Page,Resize Page Blob,Set Page Blob Sequence Number,Create Append Blob,Append Block,Append Block Seal,Copy Blob,Copy Blob From URL.Property-level operations are unchanged: Azurite already supports snapshot
tags, and this change is scoped to operations that write blob content.
Tests
tests/blob/apis/blob.test.tsgains one test that addresses every write typeat a snapshot URL, asserts each request fails with
400 InvalidOperation, andthen verifies the base blob's content, length, and bytes are untouched.
npm run buildnpx eslint "src/**/*.ts"blob.test.ts: 140 passingpageblob.test.ts,appendblob.test.ts,blockblob.test.ts: 188 passingChangeLog.mdupdated under Upcoming Release / Blob.Supersedes #2863: that PR only guards
Put Bloband has since gone stale andconflicting with
main; this one covers the remaining content-write paths.