Is your feature request related to a problem?
The current prompt injection mitigation (v2.10.2) neutralizes @@CORTEX_ in ObsidiBot-controlled content and instructs Claude to suppress triggers found in files it reads. This closes the primary attack vectors but leaves room for deeper hardening at the code layer.
Describe the solution you'd like
Two complementary improvements:
1. Action payload validation in the router
Before executing any bridge action, validate its structure and content in UIBridge.ts:
run-command: reject any commandId not on the allowlist (currently this already exists, but make it explicit and auditable)
show-notice: cap message length and strip any characters that could be rendered as UI chrome
open-file / open-file-split / navigate-heading: validate that path resolves to a file within the vault root — reject absolute paths or path-traversal sequences (../)
open-settings: validate tab against a known list of tab IDs
The goal: even a successfully injected action has a constrained blast radius because the payload is validated before execution.
2. Per-session nonce in action prefix
Inject a short random session token into the orientation at session start, and require Claude to include it in every action it emits. The router validates the token before firing.
Example: token a3f9 → Claude emits @@CORTEX_ACTION:a3f9 {"action": ...}, router checks token matches current session before executing.
This raises the bar for replay attacks and makes captured trigger strings from vault notes invalid outside the session they were observed in.
Describe alternatives you've considered
Time-based rotating token (TOTP-style): Similar to the session nonce but rotates on a schedule (hourly, etc.). Limits the window for a replayed captured token. Same fundamental weakness as the nonce — the token lives in Claude's context window and could theoretically be extracted by a sophisticated injection.
Public/private key signing: Not viable — Claude is a language model, not a cryptographic verifier. Any scheme that requires Claude to hold and use a credential is reducible to the nonce approach.
Use Case
Defense-in-depth for users with sensitive vaults who import community skills, shared templates, or external content. The action validation layer is the most impactful: it limits what a successful injection can actually do regardless of how it got through.
Additional Context
Discussed in the context of the v2.10.0 security review (S1 — prompt injection via @@CORTEX_ACTION). The current fix addresses the primary injection paths; these improvements address residual risk.
The fundamental ceiling: any secret ObsidiBot communicates to Claude so it can produce valid actions is a secret Claude can potentially be tricked into revealing. The nonce raises the bar but does not close the hole completely. Action payload validation at the router level is the more robust of the two approaches.
Implementation Suggestions
- Action validation: extend
executeAction in UIBridge.ts with a validation step before the switch statement
- Session nonce: generate in
ClaudeView.ts at session start (crypto.randomUUID().slice(0, 8)), inject into orientation via ContextManager, parse and strip from action lines in ClaudeProcess.ts before routing
Is your feature request related to a problem?
The current prompt injection mitigation (v2.10.2) neutralizes
@@CORTEX_in ObsidiBot-controlled content and instructs Claude to suppress triggers found in files it reads. This closes the primary attack vectors but leaves room for deeper hardening at the code layer.Describe the solution you'd like
Two complementary improvements:
1. Action payload validation in the router
Before executing any bridge action, validate its structure and content in
UIBridge.ts:run-command: reject anycommandIdnot on the allowlist (currently this already exists, but make it explicit and auditable)show-notice: capmessagelength and strip any characters that could be rendered as UI chromeopen-file/open-file-split/navigate-heading: validate thatpathresolves to a file within the vault root — reject absolute paths or path-traversal sequences (../)open-settings: validatetabagainst a known list of tab IDsThe goal: even a successfully injected action has a constrained blast radius because the payload is validated before execution.
2. Per-session nonce in action prefix
Inject a short random session token into the orientation at session start, and require Claude to include it in every action it emits. The router validates the token before firing.
Example: token
a3f9→ Claude emits@@CORTEX_ACTION:a3f9 {"action": ...}, router checks token matches current session before executing.This raises the bar for replay attacks and makes captured trigger strings from vault notes invalid outside the session they were observed in.
Describe alternatives you've considered
Time-based rotating token (TOTP-style): Similar to the session nonce but rotates on a schedule (hourly, etc.). Limits the window for a replayed captured token. Same fundamental weakness as the nonce — the token lives in Claude's context window and could theoretically be extracted by a sophisticated injection.
Public/private key signing: Not viable — Claude is a language model, not a cryptographic verifier. Any scheme that requires Claude to hold and use a credential is reducible to the nonce approach.
Use Case
Defense-in-depth for users with sensitive vaults who import community skills, shared templates, or external content. The action validation layer is the most impactful: it limits what a successful injection can actually do regardless of how it got through.
Additional Context
Discussed in the context of the v2.10.0 security review (S1 — prompt injection via
@@CORTEX_ACTION). The current fix addresses the primary injection paths; these improvements address residual risk.The fundamental ceiling: any secret ObsidiBot communicates to Claude so it can produce valid actions is a secret Claude can potentially be tricked into revealing. The nonce raises the bar but does not close the hole completely. Action payload validation at the router level is the more robust of the two approaches.
Implementation Suggestions
executeActioninUIBridge.tswith a validation step before the switch statementClaudeView.tsat session start (crypto.randomUUID().slice(0, 8)), inject into orientation viaContextManager, parse and strip from action lines inClaudeProcess.tsbefore routing