-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Convert.FromBase64XYZ decoder should reject input when unused bits are not set to 0 #121044
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implements RFC 4648 Section 3.5 compliance by rejecting Base64 input where unused bits are not set to zero. Co-authored-by: stephentoub <[email protected]>
Co-authored-by: stephentoub <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements RFC 4648 Section 3.5 compliance by making Convert.FromBase64XYZ methods reject Base64 input where unused bits are not set to zero, ensuring deterministic decoding where only one valid encoding exists for each byte sequence.
Key Changes:
- Modified validation logic in
Convert.Base64.csto check unused bits in Base64 padding scenarios - Updated test cases to use valid encodings and added comprehensive tests for unused bit validation
- Fixed one test data value that contained an invalid encoding
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/libraries/System.Private.CoreLib/src/System/Convert.Base64.cs |
Added bitwise checks to validate that unused bits are zero when padding is present |
src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromBase64.cs |
Replaced tests that relied on invalid encodings with valid ones, and added new tests to verify unused bit rejection behavior |
src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.cs |
Corrected test data to use a valid Base64 encoding with zero unused bits |
|
Tagging subscribers to this area: @dotnet/area-system-runtime |
Summary
Implements RFC 4648 Section 3.5 compliance by rejecting Base64 input where unused bits are not set to zero. This ensures that decoding is deterministic—only one valid encoding exists for each byte sequence.
Fixes #105262
Problem
When the input is not a multiple of 3 bytes, some bits of the encoded values are not used. The encoder sets these bits to 0, but the decoder was not validating this constraint, allowing multiple different encoded strings to decode to the same value.
For example, when encoding a single byte
[65](ASCII 'A'), the encoder produces"QQ==". However, the decoder previously accepted 16 different variations ("QQ==","QR==","QS==", ...,"Qf=="), all decoding to the same value because the last 4 bits of the second character were not validated.Changes
Updated
Convert.Base64.csto validate unused bits in theTryDecodeFromUtf16method:=): validates last 2 bits of the 3rd character are 0==): validates last 4 bits of the 2nd character are 0This brings
Convert.FromBase64XYZmethods in line with the existing validation inBase64DecoderHelper.cs(used bySystem.Buffers.Text.Base64andSystem.Buffers.Text.Base64Url).RFC 4648 Section 3.5
The specification states that unused bits MUST be set to zero by conforming encoders, and decoders MAY reject input if these bits are not zero. This change enforces that rejection.
Testing
Breaking Change
This is a breaking change, but justified because:
Convert.ToBase64XYZmethods always set unused bits to 0System.Buffers.Text.Base64andBase64UrldecodersOriginal prompt
Fixes #105264
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.