Back to skill

Security audit

抖音违禁词检测

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent Douyin compliance-checking purpose, but its URL fetching and command-invocation guidance create review-worthy security risks before installation.

Review before installing. Use it only on content you are comfortable sending to RedFox, avoid private/internal URLs, and do not run shell commands that embed raw user or webpage text. Prefer passing content via stdin, a safe argument-array call, or a temporary file, and consider disabling shell-profile credential scraping and automatic output-file writes unless you need them.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
references/core_workflow.md:33
Finding
Shell Command Injection Through Documented User-Content Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `references/core_workflow.md:33-49`; related invocation guidance in `SKILL.md:151-153` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code Snippet ```markdown - **Reply 2**: Split the content into 3,000-character batches at natural sentence boundaries, and invoke `python scripts/check_sensitive_words.py --content="..."` for each batch. - **Text input**: 1. First calculate the character count. 2. If it does not exceed 3,000 characters, directly invoke `python scripts/check_sensitive_words.py --content="copy content"`. - **Text file input**: 1. Invoke `python scripts/check_sensitive_words.py --file=/path/to/file.txt --extract-only`. 2. If the returned length does not exceed 3,000, directly invoke `python scripts/check_sensitive_words.py --content="extracted content"`. - **Web address**: 1. Invoke `python scripts/check_sensitive_words.py --url=https://example.com --extract-only`. 2. If the returned length does not exceed 3,000, directly invoke `python scripts/check_sensitive_words.py --content="extracted content"`. ``` The related quick-reference instructions in `SKILL.md:151-153` likewise direct the agent to place text into a quoted `--content="..."` argument. ### Technical Analysis The workflow instructs the agent to insert attacker-controlled copy or extracted website content directly into a command-line template. If the agent executes this template through a shell, double quotes do not prevent shell command substitution. Constructs such as `$(command)` and backticks are evaluated by common POSIX shells even when they occur inside double quotes. Other shell metacharacters and crafted quoting can also alter command parsing depending on how the agent constructs the final command. The Python script itself uses `argparse` safely once started; the vulnerability occurs before Python receives the argument, during shell interpretation. ### Attack Path 1. An ...[truncated 1510 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never construct a shell command by interpolating user-controlled text. 2. Launch the script with an argument-array process API and disable shell processing. For example: ```python subprocess.run( ["python", "scripts/check_sensitive_words.py", "--content", content], shell=False, check=True, text=True, capture_output=True, ) ``` 3. Prefer passing arbitrary content over standard input or through a securely created temporary file. This avoids command-line parsing risks and operating-system argument-length limits. 4. Update `references/core_workflow.md` and `SKILL.md` to explicitly prohibit `shell=True`, `os.system`, shell-form tool invocations, and string-built commands. 5. If only a shell-based tool interface is available, redesign the script to read content from standard input rather than relying only on `--content`. 6. Treat text extracted from files and websites as untrusted input subject to the same protections as directly supplied user content. 7. Add regression tests containing command substitutions, backticks, quotes, semicolons, newlines, and other shell metacharacters, verifying that they are passed literally and never executed. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check_sensitive_words.py:103
Finding
Server-Side Request Forgery Through Unrestricted URL Extraction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check_sensitive_words.py:103-151` **Vulnerability Type**: Server-Side Request Forgery **Risk Level**: High ### Vulnerable Code Snippet ```python def extract_from_web(url): """ Extract text from a web page. Prefer Playwright to render JavaScript, then fall back to static extraction through requests. """ if not url.startswith(('http://', 'https://')): url = 'https://' + url try: from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(url, timeout=30000) page.wait_for_timeout(3000) article_selectors = [ 'article', '.article-content', '.article-body', '.article-detail', '.post-content', '.post-body', '.content-body', '.entry-content', '.rich_media_content', '#js_content', '.detail-content', '.article-content', '.news-content', '.text-content', ] text = None for selector in article_selectors: try: el = page.query_selector(selector) if el: extracted = el.inner_text().strip() if len(extracted) > 100: text = extracted break except Exception: continue if not text: text = page.inner_text('body') browser.close() return text.strip() except Exception: pass try: resp = requests.get(url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept": "text/html, */*" }, timeout=30) resp.raise_for_status() ``` ### Technical Analysis The function accepts a user-cont ...[truncated 2687 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer a strict allowlist of approved public domains when the business requirement permits it. 2. Parse URLs with a standards-compliant URL parser and accept only explicit `http` and `https` schemes. 3. Reject URLs containing credentials, ambiguous host syntax, unsupported ports, or malformed hostnames. 4. Resolve the hostname before connecting and reject every resolved address that is loopback, private, link-local, multicast, unspecified, reserved, or otherwise non-global. 5. Protect against DNS rebinding by connecting to the validated address while preserving the intended hostname for TLS verification, or enforce equivalent controls through a hardened outbound proxy. 6. Disable automatic redirects or validate the destination of every redirect using the same scheme, hostname, and IP-address checks. 7. For Playwright, intercept all browser requests and block unsafe navigation targets, frames, scripts, images, and other subresources. Validating only the top-level URL is insufficient. 8. Apply outbound firewall or sandbox rules that prevent access to loopback, private networks, cluster-local services, and metadata ranges such as link-local infrastructure endpoints. 9. Limit response size, navigation time, redirect count, and downloaded resource volume to reduce denial-of-service exposure. 10. Avoid automatically forwarding fetched internal-looking content to third-party APIs. Clearly disclose and obtain authorization before transmitting extracted page content. 11. Add tests covering IPv4 and IPv6 loopback, private ranges, encoded IP representations, DNS names resolving to private addresses, redirect chains, and DNS-rebinding scenarios. ]]>
Vulnerability Patterns
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (20)

Tainted flow: 'headers' from os.getenv (line 202, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
last_error = None
        for attempt in range(3):  # 最多3次(1次原始 + 2次重试)
            try:
                response = requests.post(
                    API_URL,
                    json=payload,
                    headers=headers,
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
The documented behavior does not accurately match the described purpose: the skill promises replacement suggestions and safe rewritten output, yet the finding indicates code does not produce them, while also exposing an undeclared extract-only mode. Security-sensitive tools must be transparent about what they do, because hidden or missing behavior can mislead users into sharing files or URLs under false assumptions and can enable unintended data extraction workflows.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
将获赠免费积分**,可立即开始使用 API 服务
4. 注册登录后,在个人中心获取 API Key,格式为 `ak_xxxxxxxx`

### 配置 API Key

将 API Key 配置为环境变量 `REDFOX_API_KEY`:

**方式一:临时设置(当前终端会话有效)**

```bash
export REDFOX_API_KEY=ak_xxxxxxxx
```

**方式二:永久设置(推荐)**

```bash
# Bash 用户
echo 'export REDFOX_API_KEY=ak_xxxxxxxx' >> ~/.bashrc
source ~/.bashrc

# Zsh 用户
echo 'export REDFOX_API_KEY=ak_xxxxxxxx' >> ~/.zshrc
source ~/.zshrc
```

| 变量名 | 必填 | 说明 |
|--------|------|------|
| `REDFOX_API_KEY` | 是 | RedFox API 访问密钥,格式 `ak_xxxxxxxx`,脚本自动通过 `X-API-KEY` 请求头附加 |

---

## 使用指南

### 基础使用

#### 1. 直接贴文案

最简单的用法,直接把抖音文案粘贴进来:

> 用户:帮我看下这段抖音脚本有没有违禁词:这款美白神器真的太有效了,用了三�
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Vague Triggers

Medium
Confidence
95% confidence
Finding
The README says users can 'directly use natural language to describe needs, no need to remember commands,' which does not define clear trigger phrases or boundaries for when the skill should activate. This broad activation guidance overlaps with ordinary conversation and lacks exclusion conditions or negative examples.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares capabilities that involve environment variables, file access, and external network use, but it does not define an explicit tool scope such as permissions or allowed-tools. That makes the operational boundary unclear and increases the chance that an agent executes broader actions than a user reasonably expects, especially given the skill reads local files, fetches URLs, and uses an API key to send data to an external service.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The privacy notice says content is sent via HTTPS to a detection service, but the warning is incomplete for uploaded files and fetched webpages, which may contain third-party or sensitive data beyond pasted text. Users may not realize that full extracted text from documents or URLs is being transmitted externally, creating a data disclosure risk in a compliance-review context where proprietary marketing copy or internal documents are common.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs the agent to automatically write a local output file and deliver it to the user, but it does not present this as an explicit consent step or warn that local filesystem writes will occur. Automatic file creation can surprise users, overwrite expectations about data handling, and leave sensitive transformed content on disk longer than intended.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation description says the skill triggers when a user enters text, uploads a file, or provides a webpage URL and needs prohibited-word checking. This is broad input-based phrasing rather than a narrow invocation phrase or constrained context, and it lacks explicit negative examples or exclusions to distinguish ordinary uploads/URLs from intentional skill use.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill fetches user-supplied URLs and may render them with a browser, but it does not clearly warn the user that external network access will occur. This matters because URL fetching can expose system network reachability, trigger requests to internal or sensitive endpoints if not constrained, and send page contents to downstream processing unexpectedly.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The workflow mandates writing derived user content to a local file and sending it back without first warning the user that local persistence will occur. This creates unnecessary data retention risk, especially if the processed content contains sensitive business copy, regulated text, or personal information, and the user may reasonably expect ephemeral processing only.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The workflow states that an API key is used and implies content is processed through an external service, but it does not clearly tell users their submitted text may leave the local environment. This is a transparency and privacy problem because users may provide sensitive marketing drafts, documents, or extracted webpage text without understanding third-party processing is involved.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill reads multiple local shell startup files to extract REDFOX_API_KEY, which expands host-data access beyond the minimum needed for prohibited-word checking. Even though it targets a specific variable, it still inspects user configuration files without explicit consent, creating unnecessary exposure to local secrets and environment context.

External Transmission

Medium
Category
Data Exfiltration
Content
last_error = None
        for attempt in range(3):  # 最多3次(1次原始 + 2次重试)
            try:
                response = requests.post(
                    API_URL,
                    json=payload,
                    headers=headers,
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
User-provided content, including text extracted from local files or webpages, is sent to an external API for analysis without an explicit user-facing warning or consent step at transmission time. If the input contains private, regulated, or confidential data, this creates an avoidable data-disclosure risk to a third party.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The extract-only mode returns raw contents from local files or arbitrary webpages without performing the advertised sensitive-word detection step. In an agent-skill context, that makes the tool capable of generic data extraction, increasing the chance it is used to retrieve or relay sensitive host or remote content outside its stated purpose.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The README is entirely in Chinese and does not state that the skill is intentionally limited to Chinese-language users or content, nor does it offer a language/locale choice. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation unless the constraint is clearly documented and justified.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The documentation mandates a fixed Chinese output structure and prescribed response wording, and the entire skill behavior is framed as Chinese-only without any opt-in or alternative locale support. Under the language/locale policy rule, forcing a specific language is a concern unless the locale restriction is explicitly justified or optional.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The script's user-facing output and CLI description are written in Chinese, and there is no option to select another language or locale. This can violate language/locale policy where tools should not force a specific language without user opt-in.

Missing User Warnings

Low
Confidence
90% confidence
Finding
The script silently reads shell configuration files in search of credentials, which may surprise users and bypass their expectations about what local data the skill accesses. While narrower than full file collection, it still touches sensitive configuration sources without transparent notice.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The CLI help text and runtime error messages shown to users are hardcoded in Chinese throughout the main entry flow. No alternate locale or opt-in mechanism is provided, so the tool enforces a single language experience.

Static analysis

No suspicious patterns detected.