Skip to content

Fix DPoP token type comparisons to be case-insensitive - #3021

Merged
wmathurin merged 1 commit into
forcedotcom:devfrom
wmathurin:fix-dpop-apply-auth-headers-case-insensitive
Sep 1, 2026
Merged

wmathurin merged 1 commit into
forcedotcom:devfrom
wmathurin:fix-dpop-apply-auth-headers-case-insensitive

Conversation

@wmathurin

@wmathurin wmathurin commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • What: Several DPoP token type comparisons across the Android SDK used case-sensitive equality (== in Kotlin, .equals() in Java) against the literal "DPoP". RFC 6749 §5.1 defines token_type as case-insensitive; servers are permitted to return any casing. The fix adds an isDPoPTokenType() helper (using equalsIgnoreCase) to DPoPKeyManager and applies it to all five call sites.
  • Why: Correctness/robustness fix per RFC 6749 §5.1. This is not confirmed as the root cause of any specific INVALID_AUTH_HEADER incident — debug logging showed the test org returns uppercase "DPoP" in refresh responses. The fix eliminates a latent failure mode for orgs/server versions that may return lowercase.
  • Scope: 5 production files + 2 test files. No behaviour change for orgs returning uppercase "DPoP".

Files changed

File Fix
DPoPKeyManager.kt Add isDPoPTokenType() helper; use in shouldAttachDPoP
OAuth2.java addAuthorizationHeader scheme + both uiSid assignments
UserAccountManagerExtension.kt upgradeToDPoP / downgradeFromDPoP early-exits
AuthenticationUtilities.kt FEATURE_DPOP telemetry registration
DevSupportInfo.kt Dev support DPoP nonce display

Test plan

  • test_isDPoPTokenType_matchesCaseInsensitivelyAndRejectsNilEmpty passes
  • test_shouldAttachDPoP_lowercaseDPoPTokenType_returnsTrue passes
  • applyAuthHeaders_lowercaseDPoPTokenType_stampsDPoPSchemeNotBearer passes
  • Full SalesforceSDK connected suite: 423/423 pass on emulator
  • Manual verification against a DPoP-enabled org

Related

GUS: W-24027018
iOS counterpart: forcedotcom/SalesforceMobileSDK-iOS#4159

Servers return lowercase "dpop" in token refresh responses per RFC 6749 §5.1.
Case-sensitive comparisons caused addAuthorizationHeader to use Bearer and
shouldAttachDPoP to return false, producing INVALID_AUTH_HEADER 401s on every
post-refresh request.

Changes:
- DPoPKeyManager: add isDPoPTokenType() helper (equalsIgnoreCase); use in shouldAttachDPoP
- OAuth2.java: switch addAuthorizationHeader and uiSid assignments to isDPoPTokenType()
- UserAccountManagerExtension: fix upgradeToDPoP / downgradeFromDPoP early-exit checks
- AuthenticationUtilities: fix FEATURE_DPOP telemetry registration
- DevSupportInfo: fix DPoP nonce display in dev support overlay
- Tests: add isDPoPTokenType case-insensitivity tests, shouldAttachDPoP lowercase regression,
  and applyAuthHeaders_lowercaseDPoPTokenType_stampsDPoPSchemeNotBearer regression test
@github-actions

Copy link
Copy Markdown
1 Warning
⚠️ libs/SalesforceSDK/src/com/salesforce/androidsdk/developer/support/DevSupportInfo.kt#L183 - This method should only be accessed from tests or within private scope

Generated by 🚫 Danger

@wmathurin
wmathurin merged commit d6326d2 into forcedotcom:dev Sep 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants