Back to skill

Security audit

reddit-digest

Security checks for vulnerabilities and agentic risk

Overview

This Reddit digest skill is mostly purpose-aligned, but its documented shell commands use unquoted user-controlled placeholders that could let a crafted subreddit or path run unintended commands.

Review before installing. Use this only with trusted subreddit names and output paths, and avoid passing arbitrary text into SUBREDDIT or BASE_DIR until the shell snippets validate and quote those values. Expect it to create local digest, temp, and log files and to run a background Reddit-fetching command.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:31
Finding

Shell Command Injection Through Unquoted Configuration Placeholders

Content
View full analysis
/tmp/reddit_fetch_{SUBREDDIT}.log 2>&1 ``` ### Technical Analysis The skill instructs the agent to interpolate `BASE_DIR`, `DATE`, and `SUBREDDIT` into shell commands. These values are configurable through command-line arguments or environment variables, but the command templates do not consistently pass them as quoted shell arguments. The first command interpolates all three values without quoting: ```bash mkdir -p {BASE_DIR}/{DATE}/{SUBREDDIT}/temp ``` In the second command, `{SUBREDDIT}` is unquoted when supplied to `autocli`, and it is also interpolated into an unquoted redirection path: ```bash autocli reddit subreddit {SUBREDDIT} ... > /tmp/reddit_fetch_{SUBREDDIT}.log ``` If an agent substitutes attacker-controlled configuration text into these templates and executes the result through a shell, shell metacharacters such as semicolons, command substitutions, pipes, or redirections can be interpreted as syntax rather than data. Although `scripts/fetch_post_details.py` invokes `autocli` using a subprocess argument array and does not use `shell=True`, that protection does not cover the shell commands prescribed by `SKILL.md`. ### Attack Path 1. An attacker causes a crafted value to be used as `SUBREDDIT` or `BASE_DIR`, either through a user request, a command-line configuration value, or a relevant environment variable. 2. For example, a malicious subreddit value could contain shell syntax resembling: ```text Cl ...[truncated 1426 chars]
Remediation
View remediation
&2 exit 1 fi ``` 2. **Validate the date independently.** Require the expected `YYYYMMDD` representation: ```bash if [[ ! "$DATE" =~ ^[0-9]{8}$ ]]; then printf 'Invalid date\n' >&2 exit 1 fi ``` 3. **Quote every variable expansion used as a shell argument or path:** ```bash TEMP_DIR="${BASE_DIR}/${DATE}/${SUBREDDIT}/temp" mkdir -p -- "$TEMP_DIR" ``` 4. **Avoid inserting the subreddit into a log filename directly.** Construct the path only after validation and quote the redirection target: ```bash LOG_FILE="/tmp/reddit_fetch_${SUBREDDIT}.log" autocli reddit subreddit "$SUBREDDIT" \ --limit 20 \ --sort top \ --time day \ --format json | python3 "$SKILL_DIR/scripts/fetch_post_details.py" \ --temp-dir "$TEMP_DIR" >"$LOG_FILE" 2>&1 ``` 5. **Prefer a wrapper implemented with argument arrays.** Move orchestration into Python and invoke external commands using `subprocess` with a list of arguments and `shell=False`. This avoids requiring the agent to assemble a shell command from user-controlled text. 6. **Constrain the output directory.** Resolve the configured base path to a canonical path and, if the product permits it, require it to remain under an approved output root. Reject unexpected traversal or sensitive system locations. 7. **Document that configuration values must never be concatenated into executable shell text.** Treat values obtained from user requests, command-line parameters, and environment variables as untrusted input. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

声明描述的是一个端到端 Reddit 每日摘要技能:先抓取某个 subreddit 的近24小时热门帖,再获取详情和评论,最后产出结构化摘要与 Markdown 文档。但提供的代码片段只是中间抓取环节:它从输入 JSON 或 stdin 读取帖子列表,对每条 post 调用 autocli reddit read 获取详情,保存到临时目录,并输出成功路径。代码没有实现 subreddit 热门帖发现逻辑,没有任何文本总结或内容生成逻辑,也没有 Markdown 文档生成。因此该代码与声明的整体用途存在明显不一致。唯一一致之处是“逐一获取帖子详情”这一子步骤。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes shell commands, reads files, and writes output files, yet it declares no explicit tool scope or permission boundaries. In an agent environment, this increases the chance of overbroad execution or misuse because the runtime may allow more capabilities than users expect, especially with filesystem writes and command execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

L05 将触发条件写为“生成 Reddit 每日摘要”等自然语言请求,但未限定必须指定单个 subreddit、时间范围或执行上下文。该表述相对宽泛,且没有负例或排除条件,容易与一般性的内容总结请求重叠,造成误触发。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs the agent to perform background execution and write files to disk, including a fixed default path and temp/log artifacts, without explicit user-facing risk disclosure or confirmation. This can surprise users, create persistent data on local systems, and complicate oversight because background jobs may continue after the immediate interaction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

L78 规定“所有内容使用简体中文撰写”,属于强制语言/locale 约束。文件中未见用户可选择其他语言的机制,也未说明该限制仅适用于特定地区或受众,因此构成自然语言层面的语言政策问题。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file’s headings, content instructions, and output examples require the generated document to be written in Chinese throughout. Because this applies across the whole template and does not offer user opt-in or explain a justified region-specific limitation, it appears to violate the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains natural-language documentation and CLI output entirely in Chinese, including the module docstring and runtime status/error messages. Under the policy, forcing a specific language without user opt-in is a locale/language policy violation unless the constraint is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/fetch_post_details.py (reported line 89)May include surrounding context.

python
return rank, output_path, "missing url"

    try:
        result = subprocess.run(
            ["autocli", "reddit", "read", url, "-f", "json"],
            capture_output=True,
            text=True,

Static analysis

No suspicious patterns detected.