Back to skill

Security audit

Redline Annotate

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent annotation purpose, but it installs a persistent global prompt hook and runs an unauthenticated local server that can write broadly under the user's home directory.

Install only if you are comfortable with a global Claude prompt hook and a localhost service that can modify files as your user. Prefer running it in a disposable workspace, stopping the server after use, and reviewing ~/.claude/settings.json and any .redline-inbox.json contents before allowing the agent to apply changes.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
server.py:29
Finding

Unauthenticated Cross-Origin Arbitrary File Write

Content
View full analysis
bool: """只允许写到用户家目录或 /tmp 下,避免任意路径写入。""" try: p = p.resolve() except Exception: return False home = Path.home().resolve() tmp = Path("/tmp").resolve() return any(str(p).startswith(str(root) + os.sep) for root in (home, tmp)) class Handler(http.server.BaseHTTPRequestHandler): def _cors(self): self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") self.send_header("Access-Control-Allow-Headers", "Content-Type") def do_POST(self): if self.path != "/feedback": return self._json(404, {"ok": False, "error": "not found"}) try: length = int(self.headers.get("Content-Length", 0)) raw = self.rfile.read(length).decode("utf-8") body = json.loads(raw) except Exception as e: return self._json(400, {"ok": False, "error": f"invalid json: {e}"}) inbox = body.get("inbox") payload = body.get("payload") if not inbox or not isinstance(payload, dict): return self._json( 400, {"ok": False, "error": "missing inbox or payload"} ) inbox_path = Path(inbox) if not is_path_allowed(inbox_path): return self._json( 403, {"ok": False, "error": f"path not allowed: {inbox_path}"} ) try: inbox_path.parent.mkdir(parents=True, exist_ok=True) inbox_path.write_text( json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8", ) except Exception as e: return self._json(500, {"ok": False, "error ...[truncated 2025 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
hook.sh:23
Finding

Untrusted Annotation Data Is Injected into Privileged Agent Instructions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
injector.sh:90
Finding

Python Code Injection Through Interpolated Paths and Environment Variables

Content
View full analysis
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Warning
Location
inject.js:53
Finding

Remote Third-Party JavaScript Is Retrieved and Executed Without Integrity Verification

Content
View full analysis
{ if (window.finder) { state.finder = window.finder; return resolve(); } const s = document.createElement('script'); s.src = 'https://unpkg.com/@medv/finder@3.1.0/finder.js'; s.setAttribute(UI_ATTR, '1'); s.onload = () => { state.finder = window.finder || null; resolve(); }; s.onerror = () => resolve(); document.head.appendChild(s); }); } ``` ### Technical Analysis Every annotated page can dynamically download JavaScript from a third-party CDN and execute it in the page context. Although the URL includes a package version, the response is not protected with Subresource Integrity, an independently verified hash, or a bundled audited copy. Consequently, the effective code executed by the Skill can differ from the code present during static review. A compromise of the package, CDN, account, or delivery path could cause arbitrary JavaScript to execute when an annotated page is opened. The remote script shares the annotated page's execution context. It can inspect DOM content, alter annotation behavior, access page-origin storage, and send requests to the Redline localhost service. ### Attack Path 1. The user generates and opens an annotated HTML page. 2. The injected Redline code creates a script element pointing to unpkg. 3. The browser retrieves the remote dependency. 4. If the dependency or CDN response has been compromised, malicious JavaScript is returned. 5. The browser executes that JavaScript in the annotated page context. 6. The script can inspect page data, manipulate annotations, make network requests, or interact with the local Redline endpoint. ### Impact Assessment A successful supply-chain compromise provides JavaScript execu ...[truncated 372 chars]
Remediation
View remediation

T06 · System Persistence

Warning
Location
install.sh:47
Finding

Global Prompt Hook and Long-Lived Local Service Create Cross-Session Persistence

Content
View full analysis
"$LOGFILE" 2>&1 & SERVER_PID=$! echo "$SERVER_PID" > "$PIDFILE" fi ``` ### Technical Analysis Installation modifies the user's global Claude settings by registering a `UserPromptSubmit` command hook. The hook therefore executes for later prompts and sessions rather than only for the project that requested annotation. The injector also starts the HTTP server with `nohup`, allowing it to survive the invoking shell and remain available after the annotation task. There is no automatic timeout or shutdown after feedback submission. These persistence mechanisms are documented and an uninstaller is provided, so they are not covert. Nevertheless, their system-wide and long-lived scope is broader than required for ann ...[truncated 1315 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (52)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The stated purpose is page annotation, but the skill also installs persistent hooks, edits agent configuration, writes under ~/.claude, removes components, and terminates processes. This mismatch can prevent users and reviewers from understanding the full security impact, especially because hook installation creates durable behavior beyond a single annotation session.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 把 `inject.css` / `inject.js` / `__RL_CONFIG__` 注入到 `</body>` 前

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 把 `inject.css` / `inject.js` / `__RL_CONFIG__` 注入到 `</body>` 前

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
94% confidence
Finding

Modifying ~/.claude/settings.json grants the skill influence over agent-global configuration and future prompt processing through hook registration. This is security-sensitive because a compromised or flawed skill can persist behavior across sessions, intercept future prompts, or create hard-to-notice changes outside the current project.

Content

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

md
`install.sh` 会自动完成:
1. 创建 `~/.claude/skills/redline` 软链接
2. 向 `~/.claude/settings.json` 添加 UserPromptSubmit hook
3. 设置脚本可执行权限

首次使用时 server 自动启动,无需手动运行。

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
88% confidence
Finding

The skill explicitly accesses files under ~/.claude, an agent configuration area that may contain sensitive logs, state, or operational metadata. Access to this directory is dangerous because it crosses from project-local annotation into agent-global data, increasing the chance of data exposure or unintended interference with agent behavior.

Content

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

md
## 调试

- 看 server 日志:`tail -f ~/.claude/redline/server.log`
- 手动起 server:`python3 server.py 7893`
- 手动测 hook:`CLAUDE_PROJECT_DIR=/path/to/project ./hook.sh`(需先在该目录放一份 inbox)
- 杀 server:`kill $(cat ~/.claude/redline/server.pid)`

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
91% confidence
Finding

Reading a PID file from ~/.claude/redline/server.pid and using it to kill a process introduces control over processes via agent-global state. If the PID file is stale, replaced, or manipulated, the wrong process could be terminated, causing denial of service or interference with unrelated tooling.

Content

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

md
- 看 server 日志:`tail -f ~/.claude/redline/server.log`
- 手动起 server:`python3 server.py 7893`
- 手动测 hook:`CLAUDE_PROJECT_DIR=/path/to/project ./hook.sh`(需先在该目录放一份 inbox)
- 杀 server:`kill $(cat ~/.claude/redline/server.pid)`

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · hook.sh (reported line 4)May include surrounding context.

sh
#!/usr/bin/env bash
# UserPromptSubmit hook for redline
#
# 配置进 ~/.claude/settings.json 后,每次用户发送 prompt 前会先跑这个脚本。
# 检查 cwd 下是否有 .redline-inbox.json:
#   有 → 把内容作为 additionalContext 注入到 prompt(连带 apply 指令)
#   无 → 静默退出,不影响正常对话

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code transmits page-derived annotation data, including snippets of DOM content, to a local HTTP service and falls back to copying the full payload to the clipboard. Both paths can expose sensitive page content without an upfront warning, and the clipboard fallback broadens exposure to any application the user pastes into afterward.

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
91% confidence
Finding

The script targets the agent configuration directory and writes to ~/.claude/settings.json, which is a sensitive control point because it can alter how the agent behaves on later runs. In this skill's context, that access is more dangerous because it is used to install a prompt-submission hook, effectively creating persistent behavior that can observe or transform future user interactions.

Content

Scanner excerpt · install.sh (reported line 18)May include surrounding context.

sh
SKILLS_HOME="$HOME/.claude/skills"
LINK_PATH="$SKILLS_HOME/redline"
SETTINGS="$HOME/.claude/settings.json"
HOOK_CMD="$SKILL_DIR/hook.sh"

echo "redline skill 安装"

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/demo.annotated.html (reported line 94)May include surrounding context.

html
<footer>
    © 2026 AcmeAI Inc.
  </footer>
<!-- redline: injected -->
<style data-rl-ui="1">
/* ============================================================
   redline injected styles

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/demo.annotated.html (reported line 94)May include surrounding context.

html
<footer>
    © 2026 AcmeAI Inc.
  </footer>
<!-- redline: injected -->
<style data-rl-ui="1">
/* ============================================================
   redline injected styles

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/fragment.annotated.html (reported line 2)May include surrounding context.

html
<html><body><h1>Hi</h1><div>x</div>
<!-- web-annotate: injected -->
<style data-wa-ui="1">
/* ============================================================
   web-annotate injected styles

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/inline.annotated.html (reported line 2)May include surrounding context.

html
<html><body><h1>Hi</h1><div>x</div>
<!-- web-annotate: injected -->
<style data-wa-ui="1">
/* ============================================================
   web-annotate injected styles

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/fragment.annotated.html (reported line 2)May include surrounding context.

html
<html><body><h1>Hi</h1><div>x</div>
<!-- web-annotate: injected -->
<style data-wa-ui="1">
/* ============================================================
   web-annotate injected styles

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · test/inline.annotated.html (reported line 2)May include surrounding context.

html
<html><body><h1>Hi</h1><div>x</div>
<!-- web-annotate: injected -->
<style data-wa-ui="1">
/* ============================================================
   web-annotate injected styles

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code appends a

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · uninstall.sh (reported line 8)May include surrounding context.

sh
set -euo pipefail

LINK_PATH="$HOME/.claude/skills/redline"
SETTINGS="$HOME/.claude/settings.json"
RL_HOME="$HOME/.claude/redline"
PIDFILE="$RL_HOME/server.pid"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares no explicit tool scope while its documented behavior requires shell execution, local networking, file reads/writes, and environment access. That increases the attack surface and makes it easier for the skill to invoke sensitive capabilities without clear user-visible boundaries or policy enforcement.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger conditions include broad natural-language phrases such as generic requests to annotate a webpage, which can cause the skill to activate unintentionally. Because activation can lead to code execution, file modification, browser launch, and server startup, overbroad triggering raises the risk of unexpected side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

整个技能说明和触发短语均以中文固定表达,未说明是否支持其他语言,也未给出用户可选择语言的机制。按规则,强制特定语言而没有用户选择或明确合理的地区限定,属于自然语言策略问题。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The installation flow modifies ~/.claude/settings.json and registers a UserPromptSubmit hook, but the skill text does not prominently warn about the persistence and security implications of changing global agent configuration. Hook installation can affect future prompts and projects, so understated disclosure materially increases risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The template explicitly instructs the agent to delete an inbox file after applying changes, but provides no user-facing notice, confirmation, or safety checks on the path. In an agentic workflow, destructive file operations tied to injected context can remove data unexpectedly or be abused if the inbox path is malformed or manipulated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The 'must execute' rm command makes deletion mandatory and unconditional, which is risky because the path comes from hook-injected context rather than being hardcoded and validated in this file. If the context is wrong, attacker-influenced, or unexpectedly broad, the model could delete an unintended file without warning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The hook reads a local project file and injects its full contents into the model prompt as additional context before every user submission, with no explicit user-facing disclosure or per-use consent. That creates a prompt-context exfiltration channel from the filesystem into the model and can cause unintended processing of stale, sensitive, or adversarially crafted local data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The injected context instructs the agent that it must run a shell command to delete a local file after applying changes, but this destructive action is only conveyed through hidden prompt augmentation rather than a visible user workflow. That means a local file operation can be induced automatically by ambient context, reducing transparency and creating risk of unintended deletion behavior if the inbox path or surrounding workflow is manipulated.

Content

No source excerpt is available for this finding.