T09 · Insecure Skill Coding Practices
- Location
reference/security.md:137- Finding
Reversible Base64 Encoding Used as a Secret-Storage Fallback
- Content
View full analysis
{ if (typeof this.app.secretStorage?.setSecret === 'function') { await this.app.secretStorage.setSecret(id, value) } else { // Fallback: store encrypted in settings (less secure) this.settings._legacy_secrets = this.settings._legacy_secrets ?? {} this.settings._legacy_secrets[id] = btoa(value) await this.saveData(this.settings) } } ``` The associated recommendation states: ```markdown 1. **Never store API keys in plain text** — use SecretStorage or at minimum base64 encode ``` ### Technical Analysis The fallback applies `btoa()` to API keys before saving them in ordinary plugin settings. Base64 is a reversible representation and provides no encryption, authentication, access control, or confidentiality. Any party capable of reading the settings can recover the original credential with a standard Base64 decoder. The comment incorrectly describes the value as “encrypted,” and the best-practice section recommends Base64 as a minimum security measure. These statements could cause an AI agent or developer to treat reversibly encoded credentials as protected. This behavior exceeds safe credential-handling requirements. Supporting older Obsidian versions does not require silently persisting reusable secrets in a recoverable format. ### Attack Path 1. A generated plugin accepts an API key or access token from the user. 2. The installed Obsidian version does not expose `SecretStorage`. 3. The fallback executes `btoa(value)` and writes the result into the plugin's normal settings data. 4. The settings file is exposed through local filesystem access, vault synchronization, backups, accidental repository commits, another plu ...[truncated 860 chars]- Remediation
View remediation
