@W-17366971: Clear encryption keys and user info SharedPreferences on logout#2848
@W-17366971: Clear encryption keys and user info SharedPreferences on logout#2848wmathurin merged 1 commit intoforcedotcom:devfrom
Conversation
… logout Addresses ASA security vulnerability (CWE-922) where identifier.xml and current_user_info files persisted after logout, containing encrypted identifiers and user data. Cleanup now occurs when the last authenticated user logs out.
Generated by 🚫 Danger |
Analysis: identifier.xml Usage in Salesforce Mobile SDK for AndroidOverviewThis document analyzes how the content of What is identifier.xml?The File Location
ContentsThe file contains entries with keys in the format:
Example from ASA report: <string name="encrypted_id_6cgs4f">xrKMKKseGRA5sA5y1hsPO+1fIJFrX3RwYdjVXu+KwYEUo1f...</string>How identifier.xml is Used1. Master Encryption Key for User Account DataLocation: val encryptionKey: String
get() = getEncryptionKey(INTERNAL_ENTROPY) // INTERNAL_ENTROPY = "6cgs4f"Purpose: Derives the master encryption key used to encrypt/decrypt:
Flow:
Impact: If this key persists after logout, it could theoretically be used to decrypt cached user data if any remnants exist. 2. SmartStore Database EncryptionLocation: SQLiteOpenHelper dbOpenHelper = DBOpenHelper.getOpenHelper(getEncryptionKey(), ...)
KeyValueEncryptedFileStore kvStore = new KeyValueEncryptedFileStore(..., getEncryptionKey())Purpose: Encrypts SmartStore databases using SQLCipher:
How it works:
Important: SmartStore databases are properly deleted on logout via 3. Analytics Data EncryptionLocation: analyticsManager = new AnalyticsManager(filenameSuffix, sdkManager.getAppContext(),
SalesforceSDKManager.getEncryptionKey(), deviceAppAttributes);Purpose: Encrypts analytics event data stored locally before upload:
Data stored: Analytics events are stored in encrypted files on disk until they can be uploaded to Salesforce servers. 4. Push Notification DecryptionLocation: final String name = SalesforceKeyGenerator.getUniqueId(PushService.PUSH_NOTIFICATION_KEY_NAME);
final String sanitizedName = name.replaceAll("[^A-Za-z0-9]", "");
rsaPrivateKey = KeyStoreWrapper.getInstance().getRSAPrivateKey(sanitizedName);Purpose: Retrieves a unique identifier to look up an RSA private key used to decrypt push notifications:
Why it matters: The unique ID acts as a stable identifier for the RSA keypair across app restarts. 5. OAuth2 PKCE Code Verifier/ChallengeLocations:
val codeVerifier: String = SalesforceKeyGenerator.getRandom128ByteKey()
val codeChallenge: String = SalesforceKeyGenerator.getSHA256Hash(codeVerifier)Purpose: Generates PKCE (Proof Key for Code Exchange) parameters for OAuth2 authentication:
Note: These use Security Implications of Not Clearing identifier.xmlHigh Risk:
Medium Risk:
Lower Risk (but still important):
Why Our Fix is AppropriateWhat We're Clearing:
When We Clear:
Defense in Depth:Even though the SDK already:
...our fix provides an additional security layer by ensuring the encryption keys themselves are removed, making it impossible to decrypt any residual data that might remain due to:
ASA Vulnerability Details (W-17366971)Category: CWE-922: Insecure Storage of Sensitive Information Threat: Physical access attacker could retrieve encrypted identifiers and potentially:
Mitigation: Clear all encryption keys and identifiers when the last user logs out. VerificationOur test case
ConclusionThe content of
The fix is necessary, safe, and follows security best practices for mobile applications. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #2848 +/- ##
============================================
+ Coverage 64.56% 64.87% +0.31%
- Complexity 2925 2964 +39
============================================
Files 222 222
Lines 17338 17380 +42
Branches 2474 2477 +3
============================================
+ Hits 11195 11276 +81
+ Misses 4936 4905 -31
+ Partials 1207 1199 -8
🚀 New features to boost your workflow:
|
Addresses ASA security vulnerability (CWE-922) where identifier.xml and current_user_info files persisted after logout, containing encrypted identifiers and user data. Cleanup now occurs when the last authenticated user logs out.