Skip to content

Conversation

@Patrick-Pimentel-Bitwarden
Copy link
Contributor

@Patrick-Pimentel-Bitwarden Patrick-Pimentel-Bitwarden commented Nov 17, 2025

NEEDS TESTING ON FEATURE BRANCH

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-22975

📔 Objective

The objective of this ticket is to create a client version validator that checks the header data on a token request and prevent users who have migrated to v2 from logging in with older client versions.

  1. Extracted out KM utilities for checking isV2Encryption from RotateUserAccountKeysCommand
  2. Added some clarity and comments in BaseRequestValidator
  3. Installed the validation for client version in the appropriate place to prevent account enumeration

📸 Screenshots

Validator.Working.mov
Non.Rotated.Key.Working.Fine.mov

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 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

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

Logo
Checkmarx One – Scan Summary & Details817d6741-4ce9-4d41-9cdc-b34ac31527ea

New Issues (6)

Checkmarx found the following issues in this Pull Request

# Severity Issue Source File / Package Checkmarx Insight
1 MEDIUM CSRF /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs: 99
detailsMethod at line 99 of /src/Api/Billing/Controllers/VNext/AccountBillingVNextController.cs gets a parameter from a user request from request. This...
Attack Vector
2 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1170
detailsMethod at line 1170 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
3 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1060
detailsMethod at line 1060 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
4 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 431
detailsMethod at line 431 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector
5 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1519
detailsMethod at line 1519 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
6 MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 1395
detailsMethod at line 1395 of /src/Api/Vault/Controllers/CiphersController.cs gets a parameter from a user request from id. This parameter value flows ...
Attack Vector
Fixed Issues (1)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
MEDIUM CSRF /src/Api/Vault/Controllers/CiphersController.cs: 300

@claude
Copy link
Contributor

claude bot commented Nov 20, 2025

Claude finished @Patrick-Pimentel-Bitwarden's task in 3m 25s —— View job


Code Review Complete

The specialized review agent has completed its analysis and posted detailed findings as inline comments and a summary review.

Review completed successfully.


@Patrick-Pimentel-Bitwarden Patrick-Pimentel-Bitwarden changed the title Auth/pm 22975/client version validator feat(auth-validator): [Auth/PM-22975] Client Version Validator Nov 20, 2025
@Patrick-Pimentel-Bitwarden Patrick-Pimentel-Bitwarden marked this pull request as ready for review November 20, 2025 19:55
@Patrick-Pimentel-Bitwarden
Copy link
Contributor Author

I am seeing 100 failures in tests, double checking what is going on, consider holding off on approving.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Finding 3: Important - Error message reveals encryption state

Location: src/Identity/IdentityServer/RequestValidators/ClientVersionValidator.cs lines 27, 67

Issue: The error message "Please update your app to continue using Bitwarden" reveals the user has v2 encryption enabled.

This creates an information disclosure vulnerability:

  1. Attacker with valid credentials but old client receives: "Please update your app"
  2. Attacker knows this account has v2 encryption (higher security)

Combined with the timing side-channel, this confirms account encryption status.

Recommendation: Use a generic error message that doesn't reveal encryption state:

private const string _upgradeMessage = "Authentication failed. Please ensure you are using the latest version of Bitwarden.";

This maintains the user experience (prompting upgrade) while not explicitly revealing the account has v2 encryption.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Finding 4: Question - SecurityVersion validation strictness

Location: src/Core/Entities/User.cs lines 237-244

Question: The comment states:

"This technically is correct but all versions after 1 are considered v2 encryption. Leaving for now with KM's blessing that when a new version comes along they will handle migration."

The current implementation only checks for SecurityVersion == 2:

private bool IsSecurityVersionTwo()
{
    return SecurityVersion == 2;
}

Questions:

  1. If SecurityVersion 3+ arrives, would those users also need client version gating?
  2. Should this be SecurityVersion >= 2 to be future-proof?
  3. Is there a planned migration strategy from KM team for when version 3 arrives?

The method name IsSecurityVersionTwo() suggests exact matching, but the comment implies >= 2 semantics. This ambiguity could cause issues if a version 3 is introduced without updating this code.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Finding 5: Technical Debt - Method name doesn't match async pattern

Location: src/Identity/IdentityServer/RequestValidators/ClientVersionValidator.cs line 11

Issue: The method ValidateAsync is synchronous:

bool ValidateAsync(User user, CustomValidatorRequestContext requestContext);

The implementation (line 31) doesn't use async or return Task<bool>. This violates .NET naming conventions where Async suffix indicates Task or Task<T> return type.

Options:

  1. Rename to Validate (breaking change for implementers)
  2. Make genuinely async by returning Task<bool>
  3. Accept the technical debt and document why it breaks convention

Impact: Low-priority but creates confusion and violates established patterns in the codebase.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Finding 6: Suggested - Add null-safety to ClientVersionValidator

Location: src/Identity/IdentityServer/RequestValidators/ClientVersionValidator.cs line 1

Suggestion: Add #nullable enable at the top of the file and make nullability explicit throughout. This would:

  • Make null-handling intent explicit
  • Enable compiler warnings for potential null reference issues
  • Align with the project's goal to enable nullable reference types (as seen in other files)

Trade-off: Requires updating CustomValidatorRequestContext and related types to be nullable-aware. Consider deferring if these types aren't ready yet.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Finding 7: Suggested - Optimize encryption type detection

Location: src/Core/Entities/User.cs lines 214-217

Suggestion: Reverse the order of checks in HasV2Encryption() to avoid string parsing for v1 users:

public bool HasV2Encryption()
{
    // Fast check first (integer comparison)
    if (!IsSecurityVersionTwo())
    {
        return false;
    }
    
    // Only parse if security version matches
    return HasV2KeyShape();
}

This leverages short-circuit evaluation to eliminate the string parsing operation when SecurityVersion != 2.

Measured benefit: Eliminates string parsing for 100% of v1 users. Neutral for v2 users.

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Positive Observations

  1. Good validation ordering: The client version check is correctly placed AFTER credential validation in BaseRequestValidator, preventing basic account enumeration.

  2. Comprehensive test coverage: Integration tests cover both blocking (v2 user + old client) and allowing (v2 user + new client) scenarios.

  3. Clean extraction: Moving encryption parsing logic from RotateUserAccountKeysCommand to EncryptionParsing.cs improves reusability.

  4. Proper DI integration: ClientVersionValidator is correctly registered and injected through the DI container.


Summary

The PR implements the core functionality correctly, but has a critical backward compatibility issue (Finding 1) that will break authentication for v1 users when clients don't send the header. The security concerns (Findings 2-3) should also be addressed before merge to prevent information leakage about account encryption state.

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Re-Review Update - PR #6588

Thank you for the feedback on my previous review. I've reconsidered Finding 1 in light of the design intent expressed in the code comments (lines 44-47 of ClientVersionValidator.cs).

Re: Finding 1 (Backward Compatibility)

I understand the intention is to establish a strict contract requiring ALL clients to send the Bitwarden-Client-Version header going forward. The comment states: "the server cannot guarantee that a client won't do harm to a user's data with stale encryption architecture."

However, I want to ensure you've considered:

  1. Deployment Timing: When this code deploys, will ALL currently-supported client versions already be sending this header? If not, legitimate v1 users on older (but still supported) clients will be unable to authenticate.

  2. Gradual Rollout: Has the header been required in clients for at least one release cycle before server-side enforcement begins?

  3. Self-Hosted Impact: Self-hosted instances may have clients that lag behind cloud versions.

If these scenarios are covered (e.g., header has been sent by clients for 6+ months, or there's a coordinated release plan), then the strict validation is appropriate. The "NEEDS TESTING ON FEATURE BRANCH" note in the PR suggests you're already aware of the need for careful validation.

Remaining Security Concerns

The other findings from my initial review remain valid:

  • Finding 2: Timing side-channel may reveal v2 encryption status through differential response times
  • Finding 3: Error message "Please update your app" explicitly reveals v2 encryption status to attackers

These information disclosure issues should be addressed regardless of the backward compatibility decision.

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

@claude
Copy link
Contributor

claude bot commented Dec 15, 2025

Updated Security Review - PR #6588

After reconsidering Finding 1 based on design intent (requiring header from all clients appears intentional), the following security concerns remain:

Finding 2: Timing Side-Channel (IMPORTANT)

Location: ClientVersionValidator.cs line 31

Issue: The validator performs user-specific checks without delay, creating timing differences between v1 and v2 users that could reveal encryption status to attackers with valid credentials.

Recommendation: Add 100-200ms delay before returning false to normalize response times.

Finding 3: Information Disclosure (IMPORTANT)

Location: ClientVersionValidator.cs lines 27, 67

Issue: Error message "Please update your app to continue using Bitwarden" explicitly reveals the account has v2 encryption enabled.

Recommendation: Use generic error message that doesn't disclose encryption state.

Finding 4: Future-Proofing Question (QUESTION)

Location: User.cs lines 237-244

Question: Method checks SecurityVersion == 2. Comment suggests versions 3+ would also be "v2 encryption". Should this be >= 2 for future compatibility?

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

quexten
quexten previously approved these changes Dec 22, 2025
@JaredSnider-Bitwarden JaredSnider-Bitwarden requested a review from a team as a code owner December 22, 2025 17:54
@Patrick-Pimentel-Bitwarden Patrick-Pimentel-Bitwarden force-pushed the auth/pm-22975/client-version-validator branch from 6e144c8 to f44cd58 Compare January 2, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants