T09 · Insecure Skill Coding Practices
- Location
SKILL.md:550- Finding
Plaintext Session Private Key in Process Environment
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 550-556
Vulnerability Type: Plaintext sensitive-data handling
Risk Level: Mediumtypescript // Session account created from various sources const sessionAccount = privateKeyToAccount( process.env.SESSION_KEY || generatePrivateKey() || hsmWallet.key )Technical Analysis
The skill recommends loading a wallet private key from the
SESSION_KEYenvironment variable. Environment variables are plaintext process configuration and may be exposed through process inspection, CI/CD settings, diagnostic output, crash reports, support bundles, container metadata, or accidental logging.This is especially sensitive because the resulting account is intended to redeem ERC-7710 or ERC-7715 delegations without repeated user interaction. Although caveats can constrain the delegated authority, possession of the session key gives an attacker the same authority as the legitimate automation service for every active delegation associated with that account.
The fallback expression also contains a logic flaw: when
SESSION_KEYis absent,generatePrivateKey()returns a private key and is therefore truthy. Consequently,hsmWallet.keyis unreachable under normal behavior. Moreover, an HSM integration should expose signing operations rather than export raw private-key material ashsmWallet.key.Attack Path
- A user follows the skill and stores a session-account private key in
SESSION_KEY. - An attacker obtains access to the process environment through compromised CI/CD access, process diagnostics, container inspection, a crash dump, or another local information-disclosure path.
- The attacker extracts
SESSION_KEYand reconstructs the session account usingprivateKeyToAccount. - The attacker obtains or observes an active permission context or signed delegation associated with that session account.
- The attacker submits delegated transactions or ...[truncated 871 chars]
- A user follows the skill and stores a session-account private key in
- Remediation
View remediation
Remediation Suggestions
- Require an HSM, cloud KMS, or server-wallet integration that performs signing internally and never exports raw private-key material.
- Do not recommend persistent private keys in environment variables. If ephemeral keys are supported, generate them with a cryptographically secure library, retain them only in memory, and clearly define rotation and recovery behavior.
- Replace the fallback chain with explicit signer-source selection and fail closed when the configured secure signer is unavailable.
- Model the HSM signer as a signing interface rather than accessing
hsmWallet.key. - Grant session accounts narrowly scoped authority with short expiry periods, low spending limits, explicit targets and methods, redeemer restrictions, and limited call counts.
- Implement key rotation, delegation revocation, access auditing, and alerts for unexpected redemptions.
- Prevent secrets from appearing in logs, telemetry, crash dumps, CI output, and support bundles.
A safer design is:
typescript if (!kmsSigner) { throw new Error('A non-exportable KMS or HSM signer is required') } const sessionAccount = createAccountFromSigner(kmsSigner)
