-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[PM-22992] Check cipher revision date when handling attachments #6451
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
base: main
Are you sure you want to change the base?
Conversation
Claude finished @nikwithak's task —— View job PR Review: Cipher Attachment Revision Date ValidationI've completed a comprehensive review of the changes implementing Summary of ChangesThis PR adds optional revision date validation to attachment endpoints to prevent data corruption from concurrent modifications using outdated encryption keys. The implementation:
Critical Issues❌ Security: Inconsistent Validation LogicLocation: The validation logic has a potential timing-based bypass: if (cipher.Id == default || !lastKnownRevisionDate.HasValue)
{
return; // No validation if lastKnownRevisionDate is null
}
if ((cipher.RevisionDate - lastKnownRevisionDate.Value).Duration() > TimeSpan.FromSeconds(1))
{
throw new BadRequestException(...);
} Issue: The 1-second tolerance window could allow race conditions where two clients with slightly different system clocks both pass validation. While this may be intentional for clock skew, it should be documented. Recommendation: Document the rationale for the 1-second tolerance in a code comment. Consider if this tolerance is sufficient for distributed systems with clock drift.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6451 +/- ##
==========================================
+ Coverage 50.72% 50.87% +0.14%
==========================================
Files 1866 1866
Lines 82696 82722 +26
Branches 7307 7321 +14
==========================================
+ Hits 41944 42081 +137
+ Misses 39154 39018 -136
- Partials 1598 1623 +25 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
New Issues (2)Checkmarx found the following issues in this Pull Request
|
public bool AdminRequest { get; set; } = false; | ||
|
||
/// The last known revision date of the Cipher that this attachment belongs to. | ||
public DateTime? LastKnownRevisionDate { get; set; } = null; |
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.
🎨 I think the = null
is redundant here
} | ||
|
||
private void ValidateCipherLastKnownRevisionDateAsync(Cipher cipher, DateTime? lastKnownRevisionDate) | ||
private void ValidateCipherLastKnownRevisionDate(Cipher cipher, DateTime? lastKnownRevisionDate) |
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.
👍🏼 Thanks for renaming this
// Extract lastKnownRevisionDate from form data if present | ||
DateTime? lastKnownRevisionDate = null; | ||
|
||
if (Request.Form.TryGetValue("lastKnownRevisionDate", out var dateValue)) | ||
{ | ||
if (!DateTime.TryParse(dateValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var parsedDate)) | ||
{ | ||
throw new BadRequestException("Invalid lastKnownRevisionDate format."); | ||
} | ||
lastKnownRevisionDate = parsedDate; | ||
} |
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.
Since we use the exact same logic in different spots, I think it's a good sign to extract this into a private method
public long FileSize { get; set; } | ||
public bool AdminRequest { get; set; } = false; | ||
|
||
/// The last known revision date of the Cipher that this attachment belongs to. |
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.
⛏️ (non-blocking): I think we can use the proper xml documentation here
/// The last known revision date of the Cipher that this attachment belongs to. | |
/// <summary> | |
/// The last known revision date of the Cipher that this attachment belongs to. | |
/// </summary> |
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.
👏🏼 Thanks for the tests
{ | ||
if (!DateTime.TryParse(dateValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var parsedDate)) | ||
{ | ||
throw new BadRequestException("Invalid lastKnownRevisionDate format."); |
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.
❓ Non-blocking. This kind of begs the question, what format are we expecting, and is this specific error being handled by the client? Or is this just a helpful hint for debugging?
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.
I believe it's the ISO8601 standard - It's more a helpful hint for debugging. If the client is getting this error message, it indicates a bug with the date format in the first place.
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-22992
📔 Objective
Adds an optional field of
lastKnownRevisionDate
to endpoints where the attachment on a Cipher is modified. If passed from the client, the date is checked against the cipher, which prevents attachments corrupting by uploading using an outdated encryption key.Related client PR (consumes this change): bitwarden/clients#16862
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:
) or similar for great changes:memo:
) or ℹ️ (:information_source:
) for notes or general info:question:
) for questions:thinking:
) or 💭 (:thought_balloon:
) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:
) for suggestions / improvements:x:
) or:warning:
) for more significant problems or concerns needing attention:seedling:
) or ♻️ (:recycle:
) for future improvements or indications of technical debt:pick:
) for minor or nitpick changes