Conversation
I´m added a Mask using 0x5A for have a mask in the Critic Variables. e.g:
I´m create a Variable using let named "secret_key" with attribute "secret_password". This Variable is in the RAM, and a Malware-Plugin installed have access this Variable and modify. And, e.g: The Variable loggedInUser have a Critic Properties ("email", "github", "website") and this Malware-Plugin access and view this Variable.
…ser data in RAM This PR introduces a security enhancement to mitigate credential scraping vulnerabilities in memory (RAM). Plain-text variables containing sensitive user info (such as emails, GitHub tokens, and websites) are vulnerable to inspection or tampering by potentially malicious third-party plugins running within the same environment. Changes implemented: - Added a security module (`security.js`) featuring simple and lightweight dynamic masking using a fixed XOR key (0x5A). - Integrated `secureUserObject` and `getDecryptedUser` inside `auth.js` to ensure data remains obfuscated while stored in RAM/localStorage, preventing crashes during UI rendering.
|
| return loggedInUser; | ||
| const rawuser = await res.json(); | ||
| loggedInUser = secureUserObject(rawuser); | ||
| localStorage.setItem(CACHE_USER_KEY, JSON.stringify(loggedInUser)); |
There was a problem hiding this comment.
When /login fails after a user has been cached, the fallback returns the stored user without decrypting its string fields. Those fields are now arrays, so the sidebar can throw when it calls name.split(" ") instead of displaying the cached user. Decrypt the parsed cache before returning it.
| export function maskCredential(secretString) { | ||
| if (!secretString) return []; | ||
|
|
||
| return Array.from(secretString).map(char => char.charCodeAt(0) ^ MASK_KEY); |
There was a problem hiding this comment.
Unicode characters are corrupted
For a name containing an emoji or another character outside the basic Unicode range, Array.from keeps the character together but charCodeAt(0) saves only its first UTF-16 unit. Unmasking cannot restore the missing unit, so the user's name is permanently changed. Mask each UTF-16 unit so fromCharCode can reconstruct the original string.
| return Array.from(secretString).map(char => char.charCodeAt(0) ^ MASK_KEY); | |
| return secretString.split("").map(char => char.charCodeAt(0) ^ MASK_KEY); |
| * In JavaScript, plain text variables reside unprotected in the RAM, | ||
| * making them vulnerable to access or modification by malicious plugins. | ||
| */ | ||
| const MASK_KEY = 0x5A; |
There was a problem hiding this comment.
Fixed mask cannot protect credentials
This fixed XOR key does not protect the cached user fields from a malicious plugin. Plugins run in the app document, so one can read the masked user from the same localStorage and reverse the key. The practical cost is that this adds masking without providing the claimed protection; that requires limiting plugin access to the data or isolating plugin execution.
How this was verified: Plugin scripts execute in the app document and can read the same localStorage entry that holds user fields encoded with the fixed XOR key.
|
Again, XOR does not protect anything here, and the user details you are trying to protect are not that sensitive |
|
With all due respect, dismissing credential obfuscation in memory as "not protecting anything" overlooks fundamental principles of defensive programming and modern application security. While a XOR mask with a static key is a lightweight mechanism, its primary objective in this context is to mitigate basic Heap Inspection / RAM Dump exploitation. In environments like Cordova/WebView where third-party plugins share the same execution context, storing sensitive customer variables (such as raw GitHub tokens and emails) in plain text makes credential scraping trivial for any malicious or compromised package. Implementing an obfuscation layer enforces a Defense in Depth strategy. It ensures that even if an attacker or a malicious script gains read access to the application's memory pool, they cannot capture valid API tokens through a simple automated plaintext string scan. We are protecting the user's entry points and automated access keys—data that should never reside unprotected in memory. |
|
I'm creating a processor named "Xenon" in SystemVerilog. And you? An application for Android cell phones? Yes. |
This PR increment a mask XOR (using 0x5A in the Variable MASK_KEY), and apply a Mask in Sensitive User Credentials (e.g: Email, WebSite, GitHub etc).
I intend to bring further security enhancements in the future, such as implementing a dynamic mask key instead of a fixed value (which currently uses 0x5A).