Back to skill

Security audit

obsidian-plugin-dev

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Obsidian plugin development guide, but it contains unsafe credential-storage advice that could lead generated plugins to store API keys in reversible Base64.

Review generated plugin code before using it, especially anything that stores API keys, sends network requests, modifies vault files, deletes files, copies builds into a live plugin folder, or pushes release tags. Do not use the documented Base64 secret fallback; require Obsidian SecretStorage or another real secure storage mechanism, and pin or locally install developer tools instead of relying on unpinned npx execution.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
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

T08 · Insecure Dependencies

Warning
Location
reference/dev-workflow.md:202
Finding

Unpinned Third-Party Package Execution Through npx

Content
View full analysis
/ ``` Related unqualified `npx eslint` commands also appear in `SKILL.md:285` and `reference/eslint-rules.md:37,186,189,192`. ### Technical Analysis When the requested executable is not already installed locally, `npx` can retrieve a package from the configured npm registry and execute it. The instruction does not specify an exact reviewed version, require installation under a lockfile, or use a local-only option. Consequently, the effective executable may change after the Skill has been reviewed. Registry compromise, account takeover, dependency confusion, or an unexpected future package release could cause arbitrary package code to run on the developer's workstation. The command itself has a legitimate development purpose, but dynamically acquiring executable tooling is broader than the minimum privilege needed for file watching and copying. ### Attack Path 1. An AI agent or developer follows the documented watch-mode command. 2. `watchexec` is not present in the project's local dependencies. 3. `npx` resolves and downloads the package from the configured registry. 4. A compromised, substituted, or unexpectedly changed package is selected. 5. Package installation hooks or the invoked executable run with the developer's operating-system permissions. 6. Malicious code accesses files and credentials available to that user, modifies build artifacts, or inserts code into the plugin output. 7. A modified plugin artifact may subsequently be loaded into Obsidian or distributed in a release. ### Impact Assessment Successful exploitation could execute arbitrary code with the invoking developer's privileges. Accessible scope may incl ...[truncated 438 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (22)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 203)May include surrounding context.

md
| ESLint Rules (28 rules) | `reference/eslint-rules.md` | ESLint setup, pre-submission audit, rule reference |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 294)May include surrounding context.

md
| ESLint Rules (28 rules) | `reference/eslint-rules.md` | ESLint setup, pre-submission audit, rule reference |

Self-Modification

High
Category
Rogue Agent
Confidence
90% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · reference/cicd-release.md (reported line 278)May include surrounding context.

md
- Obfuscated code
- Dynamic/remote-loaded ads
- Client-side telemetry
- Self-update mechanisms
- Themes loading network assets

## Best Practices

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · reference/cicd-release.md (reported line 233)May include surrounding context.

  1. Fork obsidian-releases

  2. Add entry to community-plugins.json:

    json
    {
      "id": "my-plugin",
    

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The fallback example describes storing secrets 'encrypted in settings' but actually uses btoa, which is only reversible base64 encoding and provides no confidentiality. This can mislead plugin developers into shipping plaintext-equivalent secret storage, exposing API keys to anyone with access to the settings data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This is a markdown file, so SQP-2 applies to omissions in the skill description. The Network Requests section demonstrates sending a bearer token and POST data to external endpoints, but it does not warn that secrets and user/system data may be transmitted off-device or advise users to review destination URLs and data handling.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/security.md (reported line 197)May include surrounding context.

md
// GET
const response = await requestUrl({
  url: 'https://api.example.com/data',
  method: 'GET',
  headers: { 'Authorization': `Bearer ${apiKey}` }
})

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/security.md (reported line 204)May include surrounding context.

md
// GET
const response = await requestUrl({
  url: 'https://api.example.com/data',
  method: 'GET',
  headers: { 'Authorization': `Bearer ${apiKey}` }
})

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The best-practices guidance says base64 encoding is a minimum acceptable alternative to plaintext storage, which is materially incorrect because base64 does not protect secrecy. In a developer skill, this advice is especially risky because it can propagate insecure handling of API keys across many plugins.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file documents a destructive operation using vault.delete(file) and only includes the internal note 'use with caution'. Under the missing-user-warnings rule for markdown, the skill description should clearly warn users about behaviors that can affect user data or system integrity, especially irreversible deletion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file advertises Vault API file CRUD, SecretStorage, and network request guidance, which are behaviors that can affect user data, privacy, or system integrity. The README presents these capabilities as features but does not include any cautionary note or warning to users about reviewing generated code before it reads/writes files, handles secrets, or makes network calls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents a release procedure that runs npm version and git push --tags, which changes project files, creates tags, and triggers the automated release pipeline. Although the steps are clear, there is no nearby user-facing warning that these commands are state-changing and may publish a release automatically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The beta release example uses npm version prerelease followed by git push --tags, which updates version metadata and pushes tags that activate the release workflow. The section does not explicitly warn users that executing these commands can publish prerelease artifacts automatically.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The instruction "Sentence case — all UI text" is a natural-language style rule that imposes a specific language/locale convention universally. Under the policy, forcing a locale or language convention without user opt-in can be a policy violation unless clearly justified as region-specific, which is not provided here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file includes commands that create or append to notes in an Obsidian vault, which can affect user data. The surrounding documentation does not warn that these commands will modify files or suggest using a test vault or verifying the target note first.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown provides cp commands that copy built artifacts into a live plugin directory, which can overwrite existing plugin files and affect the user's test environment. There is no nearby warning about overwriting files, confirming the destination path, or backing up existing plugin contents.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.