T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:37
- Finding
- Persistent plaintext storage of LLM API credentials in browser localStorage<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 37 **Vulnerability Type**: Client-side plaintext credential storage **Risk Level**: High ### Vulnerable Code Snippet ```markdown - **API 设置**:页面内置设置弹窗,用户自行配置 LLM API endpoint/key,存储在 localStorage ``` English translation: The page provides a settings dialog in which users configure an LLM API endpoint and key, and stores the configuration in `localStorage`. ### Technical Analysis The documented design persistently stores an LLM API key in browser `localStorage`. Values in `localStorage` are neither encrypted nor protected from JavaScript running under the same origin. They also remain available after the browser tab or session is closed. Consequently, any script that gains execution within the application origin can read the credential. Possible sources include a cross-site scripting vulnerability, a compromised third-party browser asset, an unsafe future application update, or other untrusted content served from the same origin. A malicious browser extension with suitable privileges may also access browser-page data. The submitted artifact contains documentation and metadata only, so the implementation of the storage operation and any compensating controls could not be inspected. The insecure persistence behavior is nevertheless explicitly specified by the Skill documentation. ### Attack Path 1. A user enters a valid LLM API key through the documented settings dialog. 2. The application persists the key in `localStorage`. 3. Attacker-controlled JavaScript obtains execution in the application's origin, such as through an application XSS flaw or a compromised executable dependency. 4. The malicious script reads the API key from its known or discoverable `localStorage` entry. 5. The script transmits the key to an attacker-controlled service. 6. The attacker uses the stolen credential directly against the configured LLM provider. ### Impact Assessment Successful exploitation exposes ...[truncated 599 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not persist provider API keys in `localStorage`, `sessionStorage`, IndexedDB, cookies readable by JavaScript, or other client-side persistent storage. 2. Route LLM requests through a trusted backend that keeps credentials in a server-side secret manager. 3. Issue narrowly scoped, short-lived session tokens to the browser instead of exposing the provider credential. 4. Apply provider-side least privilege, spending limits, request quotas, expiration, and origin or network restrictions where supported. 5. If a client-only architecture is unavoidable, retain the key only in memory for the active page and require the user to re-enter it after reload. 6. Clearly warn users that browser-side credentials can be exposed by scripts executing in the same origin. 7. Deploy a restrictive Content Security Policy, avoid inline scripts, pin required assets to reviewed versions, and prevent unrelated applications from sharing the origin. 8. Ensure logs, exported configuration, diagnostic reports, and error messages redact API keys. ]]>
