F-2025-0002·key-management

Storing agent's temporary private keys in localStorage (client-side)

Fixedpentesttypescriptbackend
TL;DR

The app generated an agent private key on the client and persisted it in localStorage. localStorage is readable by any JavaScript in the page, so any XSS or malicious extension could exfiltrate private keys and drain funds.

Severity
HIGH
Impact
HIGH
Likelihood
HIGH
Method
MManual review
CAT.
Complexity
LOW
Exploitability
HIGH
02Section · Description

Description

The app generated an agent private key on the client and persisted it in localStorage. localStorage is readable by any JavaScript running in the page, so any XSS vulnerability or malicious extension could exfiltrate private keys and drain funds or impersonate users.

typescript
// src/utils/generateAccount.ts
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
export const generateAgentAccount = (): Agent => {
const privateKey = generatePrivateKey();
const { address } = privateKeyToAccount(privateKey);
return { privateKey, address: address as `0x${string}` };
};
typescript
// src/utils/store.ts (persists the whole user object to localStorage)
localStorage.setItem(
`liqhub_trader.user_${state.user.address}`,
JSON.stringify(updatedUser)
);
03Section · Impact

Impact

The app stores user private keys in localStorage, which is directly readable by any JavaScript in the page. This makes keys exfiltratable via a single XSS, compromised third-party script, or malicious browser extension.

Full compromise of any wallets generated by the app: an attacker can sign transactions, withdraw funds, and impersonate the user on third-party services.

04Section · Recommendation

Recommendation

  • Do not store private keys in browser storage.
  • If an automated agent is required, do server-side signing: create ephemeral keys on the server in a secure vault (HSM/KMS or at least an encrypted server-side store), and only expose signed transactions or operations via authenticated APIs. Prefer HSM/KMS (AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault).
  • If client-side ephemeral keys are required, keep them only in memory (never persisted) and use short-lived signatures and authorization.

Ipal Network: Confirmed. The team proposed clearing the key whenever the user disconnects and generating a new one on next login. Zealynx: Fixed. We agree with the proposed solution.

Status
Fixed
F-2025-0002