Back to skill

Security audit

Douyin Scraper

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a Douyin scraping helper, but it needs review because it installs and runs browser automation with broad triggers, unsafe install/runtime choices, and some advertised results are mock data.

Install only if you are comfortable with a skill that downloads browser tooling, makes live requests to Douyin, and may save results to local files. Prefer the Python path over the Node path, avoid running it with sensitive workspace mounts or credentials, treat mock=true or Node results as demo data, and review/pin dependencies before use.

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

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unbounded Playwright Dependency Installation

Content
View full analysis
=1.40.0 ``` The primary installer also installs the latest available Playwright release without using a lock file or hashes: ```bash pip install --upgrade pip pip install playwright ``` ### Technical Analysis The dependency constraint accepts every Playwright release from version 1.40.0 onward. In addition, `install.sh` bypasses `requirements.txt` and directly asks the configured Python package index for the latest Playwright package. This makes installation non-reproducible and allows code published after the skill was audited to execute in the environment. Python package installation can execute package build hooks, while the installed Playwright code is subsequently imported and run by `scripts/scraper.py`. No evidence indicates that the current Playwright package is malicious. The vulnerability is the absence of version locking and integrity verification, which unnecessarily exposes installation to future upstream compromise, a compromised package index, or dependency resolution changes. ### Attack Path 1. An attacker compromises an accepted Playwright release, its package publication account, or the package index used by `pip`. 2. The attacker publishes a newer release that still satisfies `playwright>=1.40.0`. 3. A user runs `install.sh` or installs from `requirements.txt`. 4. `pip` resolves and installs the attacker-controlled release because no exact version or hash is required. 5. Malicious package code executes during installation or when `scripts/scraper.py` imports `playwright.sync_api`. 6. The payload receives the privileges of the account running the installer or scraper. ### Impact Assessment Successful exploitation could allow arbitrary code execution with the invoking user's privileges. Depending on that account's permissions, the attacker coul ...[truncated 388 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/douyin_scraper.js:34
Finding

Chromium Sandbox Explicitly Disabled While Processing Remote Content

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
install_playwright_docker.py:28
Finding

Browser Binary Download Redirected to Unofficial Mirrors

Content
View full analysis
None: env = os.environ.copy() env.setdefault("PLAYWRIGHT_DOWNLOAD_HOST", "https://npmmirror.com/mirrors/playwright") env.setdefault("PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST", "https://cdn.npmmirror.com/binaries/chrome-for-testing") venv_python = Path("venv/bin/python") venv_pip = Path("venv/bin/pip") if not venv_python.exists(): run([sys.executable, "-m", "venv", "venv"]) run([str(venv_pip), "install", "-r", "requirements.txt"], env=env) run([str(venv_python), "-m", "playwright", "install", "chromium"], env=env) ``` ### Technical Analysis Native installation defaults Playwright's browser downloads to `npmmirror.com` and `cdn.npmmirror.com` rather than the upstream Playwright distribution endpoints. Chromium is executable software and becomes part of the skill's trusted computing base. HTTPS protects transport to the selected mirror, but it does not establish that the mirror is equivalent to or controlled by the upstream publisher. If the mirror, its storage, DNS, certificate issuance path, or publication pipeline is compromised, users may receive a modified browser binary. The script does not independently pin or verify a documented browser artifact digest before executing it. No evidence from the audited files demonstrates that these mirrors currently distribute malicious content. The risk comes from silently selecting a third-party software source without explicit user approval or independent integrity enforcement. ### Attack Path 1. An attacker compromises one of the configured mirror services or its artifact publication pipeline. 2. The attacker substitutes a malicious Chromium archive for the version requested by Playwright. 3. A user runs `python install_playwright_docker.py native`. 4. Play ...[truncated 848 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose describes an operational Douyin scraping skill with natural-language search handling and content extraction. The supplied code does not implement scraping, search, keyword extraction, ranking retrieval, or result formatting. Instead, it only prepares the runtime environment by installing Playwright and dependencies using Docker or a local venv. While this may support the scraper indirectly, the chunk’s actual behavior is materially different from the declared primary purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description promises a user-facing skill that activates on natural-language requests like '搜索一下海鲜视频', extracts keywords automatically, and scrapes Douyin search results and hot rankings into JSON/CSV/Markdown. The code instead provides a command-line scraper interface requiring structured arguments (search <keyword> or hot [category]). While it does launch Playwright and navigate to Douyin search/hot URLs, it does not parse page content; both searchVideos and getHotVideos fabricate sample VideoData objects with synthetic counts/titles. It also only saves JSON or CSV, not Markdown. Therefore the implementation only partially overlaps with the declared purpose and materially fails to deliver several core advertised behaviors.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description mostly matches the overall purpose: this is indeed a Douyin-oriented search/hotlist tool with natural-language parsing and optional Playwright usage. However, there are material discrepancies. First, the description claims output in JSON/CSV/Markdown, but the code only supports JSON and CSV. Second, the description says it uses Playwright to scrape both search results and hot rankings, but the code explicitly implements real scraping only for search and returns mock data for hot rankings. Third, the description suggests a crawler for '爆款视频和文案' with structured result extraction, but the actual real scraper only extracts anchor text and URL from search pages; the richer metadata fields and descriptive content are only present in mock fallback data. These are significant enough to count as a description-behavior mismatch, though the primary domain and intent are aligned.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill advertises very broad trigger phrases like general requests to search, look up, or find content, which overlap with ordinary user conversation. In an agent that auto-loads skills from natural language, this can cause over-triggering and unintended execution of shell-driven scraping workflows, increasing the chance of unnecessary browser automation, network access, dependency installation, or file output without clear user intent.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · install_playwright_docker.py (reported line 30)May include surrounding context.

python
def mode_native() -> None:
    env = os.environ.copy()
    env.setdefault("PLAYWRIGHT_DOWNLOAD_HOST", "https://npmmirror.com/mirrors/playwright")
    env.setdefault("PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST", "https://cdn.npmmirror.com/binaries/chrome-for-testing")
    venv_python = Path("venv/bin/python")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README describes scraping Douyin content and saving results to JSON/CSV/Markdown, but it does not prominently warn that activation causes external network requests, automated browser activity, and persistence of collected data to disk. In this skill context, that omission matters because the skill is designed for natural-language triggering, so a user may not realize a simple query will launch scraping and create local artifacts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README declares very broad natural-language triggers like '搜索一下xxx' and '看看xxx相关内容', which overlap with ordinary conversational requests and can cause the agent to invoke web scraping unexpectedly. In an agentic environment, this creates unintended side effects—network access, automated browsing, and collection/export of third-party data—based on ambiguous user phrasing rather than explicit tool consent.

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.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares no explicit tool scope while instructing the agent to change directories, run shell commands, execute installers, and write output files. In an agent ecosystem, missing scope boundaries increases the chance that this skill is invoked with broader-than-necessary shell and filesystem access, enabling unintended command execution or file modification if the skill is triggered in the wrong context.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

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

md
### 入口短语 → 关键词 → 命令 映射表

| 用户输入                              | 提取关键词     | 推荐命令                                                                                        |
|---------------------------------------|----------------|-------------------------------------------------------------------------------------------------|
| 搜索一下海鲜视频                      | 海鲜           | `python scripts/scraper.py nl "搜索一下海鲜视频"`                                               |
| 帮我找抖音上的减肥餐                  | 减肥餐         | `python scripts/scraper.py nl "帮我找抖音上的减肥餐"`                                            |

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example phrases are very broad, natural-language requests such as '搜索一下...' and '帮我找...' that are likely to overlap with ordinary user intent in many contexts. Because this skill auto-activates on common phrasing and then launches scraping behavior, it increases the risk of unintended invocation, causing unauthorized browsing/scraping actions or data collection when the user did not explicitly mean to use this skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This shell script presents all user-facing comments and echoed instructions in Chinese, which imposes a specific language on users without any opt-in or alternative. The policy allows locale constraints only when 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 · install_playwright_docker.py (reported line 14)May include surrounding context.

python
def run(cmd: list[str], cwd: str | None = None, env: dict[str, str] | None = None) -> None:
    print("\n>>>", " ".join(cmd))
    subprocess.run(cmd, cwd=cwd, env=env, check=True)


def mode_official() -> None:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function claims to scrape Douyin search results but constructs fabricated placeholder entries instead of extracting real page data. This is dangerous because downstream users or agents may trust the output as authentic market or content intelligence, leading to deceptive automation, bad decisions, or false reporting.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The hot-list path advertises retrieval of trending Douyin content but returns hardcoded sample rows. In an agent skill, this can silently poison analytics or user decisions because the data looks structured and plausible while being entirely synthetic.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring and CLI examples are entirely Chinese and present the natural-language interface as expecting Chinese phrases such as “搜索一下海鲜视频”. For an all-file-types policy check, this is a language/locale constraint expressed in natural language without any opt-in, alternative language support, or justification that the skill is intended only for a Chinese-speaking or China-specific environment.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring describes a general scraping implementation that prefers real Playwright access and falls back to local mock data when scraping fails. However, the hot path never attempts real fetching at all and directly returns mock data, which contradicts the stated behavior rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest explicitly says the skill outputs JSON/CSV/Markdown, but every CLI path only accepts json or csv and dispatches to write_json or write_csv. There is no Markdown formatter or option anywhere in the file, so the implemented behavior is narrower than the documented capability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill examples and heading are written only in Chinese, which can imply a fixed language expectation for use of the skill. There is no indication that users may interact in another language or that the Chinese-only scope is an intentional, justified regional constraint.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The dependency specification uses a lower-bound version constraint (playwright>=1.40.0) without an upper bound or exact pin, which can lead to non-reproducible installs and accidental adoption of a newly released vulnerable or breaking version through the supply chain. In a scraping skill that relies on browser automation, unexpected dependency changes can also silently alter runtime behavior and stability, increasing operational and security risk.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
playwright>=1.40.0

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script performs filesystem writes via fs.writeFileSync and only logs after the write succeeds. There is no confirmation prompt, pre-write warning, or usage text warning that providing an output path will create or overwrite a local file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CSV save path is written directly with fs.writeFileSync, but the script does not warn users that running the command with an output filename will persist scraped data to disk. The post-write log is not a disclosure before the safety-relevant operation occurs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.