Back to skill

Security audit

Douyin Content Tracker Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do what it claims, but it handles authenticated Douyin cookies and downloaded files in ways that could expose sessions or write outside the intended output folder.

Install only if you are comfortable giving the skill an authenticated Douyin session and letting it scrape, download media, and write persistent outputs locally. Use a dedicated account, keep cookie files out of sync/shared folders and source control, pin dependencies and MediaCrawler to reviewed versions, and fix the blogger-name path sanitization before running on untrusted creator data.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/download_video.py:253
Finding

Untrusted creator nickname can escape the intended audio output directory

Content
View full analysis
|]', "_", title) save_path = AUDIO_DIR / blogger / f"{video_id}.m4a" ``` The creator nickname originates from MediaCrawler output and is copied into the normalized dataset without path validation: ```python nickname = item.get("nickname") or blogger_name records.append({ "博主昵称": nickname, "视频标题": item.get("title") or item.get("desc", ""), "视频链接": item.get("aweme_url", ""), ... }) ``` ### Technical Analysis The `blogger` value is remotely sourced creator metadata. It is used directly as a filesystem path component, while only the unrelated `title` value is sanitized. `pathlib.Path` does not automatically confine joined paths to the original base directory. Values containing directory separators, parent-directory components such as `..`, or an absolute path can cause `save_path` to resolve outside `AUDIO_DIR`. The resulting path is passed to ffmpeg with the overwrite option: ```python [ FFMPEG_EXE, "-headers", headers, "-i", video_url, "-vn", "-acodec", "copy", "-y", str(save_path), ] ``` The retry error path may also delete the selected file: ```python if save_path.exists(): save_path.unlink() ``` Although subtitle filenames are sanitized elsewhere, that protection is not applied at this audio-writing sink. ### Attack Path 1. An attacker controls or influences a tracked Douyin creator nickname. 2. MediaCrawler returns the nickname in creator metadata. 3. `scrape_profile.py` stores it in the `博主昵称` CSV field. 4. `clean_data.py` renames the field to `博主` without sanitizing its contents. 5. `download_video.py` joins the untrusted valu ...[truncated 795 chars]
Remediation
View remediation
str: value = re.sub(r'[\\/:*?"<>|\x00-\x1f]', "_", str(value)).strip() value = value.strip(". ") if not value or value in {".", ".."}: return fallback return value[:100] safe_blogger = safe_component(blogger, "unknown_creator") save_path = (AUDIO_DIR / safe_blogger / f"{video_id}.m4a").resolve() audio_root = AUDIO_DIR.resolve() if save_path.parent != audio_root and audio_root not in save_path.parents: raise ValueError("Audio output path escapes AUDIO_DIR") ``` 3. Validate `video_id` against the expected Douyin identifier format before using it as a filename. 4. Perform downloads into a securely created temporary file under `AUDIO_DIR`, validate the result, and atomically rename it to the final destination. 5. Do not unlink a path unless its resolved location has first been verified to remain under the approved audio directory. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scrape_profile.py:56
Finding

Douyin authentication cookies are exposed in child-process command-line arguments

Content
View full analysis
str: """将 .douyin_cookies.json 转为 key=val; key2=val2 格式字符串""" if not COOKIE_FILE.exists(): return "" cookies = json.loads(COOKIE_FILE.read_text(encoding="utf-8")) return "; ".join(f"{c['name']}={c['value']}" for c in cookies if c.get("name")) ``` ```python def run_mediacrawler(creator_url: str, save_path: Path, limit: int) -> bool: """调用 MediaCrawler subprocess 采集博主主页""" ensure_mediacrawler_ready() cookie_str = load_cookie_string() fetch_count = max(limit * 2, 20) if limit > 0 else 50 original_cfg = set_mediacrawler_max_count(fetch_count) cmd = [ sys.executable, str(MEDIACRAWLER_DIR / "main.py"), "--platform", "dy", "--lt", "cookie" if cookie_str else "qrcode", "--type", "creator", "--creator_id", creator_url, "--get_comment", "no", "--get_sub_comment", "no", "--save_data_option", "jsonl", "--save_data_path", str(save_path), ] if cookie_str: cmd += ["--cookies", cookie_str] print(f" 启动 MediaCrawler(CDP 模式)... 路径:{MEDIACRAWLER_DIR}") try: result = subprocess.run( cmd, cwd=str(MEDIACRAWLER_DIR), capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=600, ) ``` ### Technical Analysis The code reads all cookies from `.douyin_cookies.json`, concatenates their names and values, and places the complete credential string into the MediaCrawler command-line argument list. Command-line arguments may be visible through operating-system process inspection interfaces, administrative monitoring tools, endpoint telemetry, crash diagnostics, or p ...[truncated 1560 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Python packages and mutable MediaCrawler source create supply-chain exposure

Content
View full analysis
Remediation
View remediation
``` 4. Record the expected MediaCrawler commit in project documentation and verify it before execution. 5. Use a dedicated virtual environment with minimum filesystem permissions rather than installing dependencies globally. 6. Add automated dependency scanning and a controlled update process that reviews release notes, lock-file changes, package provenance, and hashes before upgrades. 7. Consider maintaining a reproducible installation manifest for Playwright browser binaries and Whisper model artifacts as well as Python packages. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (44)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 41)May include surrounding context.

3. 配置环境变量

bash
cp .env.template .env

编辑 .env,至少填写:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 121)May include surrounding context.

3. 配置环境变量

bash
cp .env.template .env

编辑 .env,至少填写:

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broad Douyin ingestion pipeline with scraping, audio download, transcription, cookie refresh, and operational workflow support. The actual code shown only cleans and standardizes already-existing CSV data files. While CSV cleaning could be a supporting component of a larger pipeline, this chunk does not implement the headline capabilities described and instead has a narrower, materially different function. Therefore the description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code is narrowly focused on scraping a Douyin creator homepage using an external MediaCrawler project, handling cookie presence/age warnings, temporarily editing MediaCrawler config, launching it, parsing its JSONL output, and exporting CSV metadata. That aligns with only one subset of the declared description: scraping creator content. However, the declared purpose describes a larger pipeline including audio download and Whisper transcription, as well as setup, daily incremental tracking, cookie refresh, and debugging. None of those major capabilities are present in this code chunk. Additionally, the description says all pipeline scripts are bundled and can run directly without extra installation beyond pip and MediaCrawler; this file explicitly requires an externally configured MEDIACRAWLER_DIR and edits files inside that external directory, so the self-contained claim is overstated. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

bash
cd $SKILL_DIR
cp .env.template .env

Edit .env — required field:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/pipeline.md (reported line 145)May include surrounding context.

bash
cd $SKILL_DIR
cp .env.template .env

Edit .env — required field:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 120)May include surrounding context.

bash
cd $SKILL_DIR
cp .env.template .env

Edit .env — required field:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/scrape_profile.py (reported line 86)May include surrounding context.

python
```bash
cd $SKILL_DIR
cp .env.template .env
```

Edit `.env` — required field:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/troubleshooting.md (reported line 74)May include surrounding context.

Model file may be corrupted (partial download). Delete and re-download:

bash
del "models\medium.pt"     # Windows
rm models/medium.pt        # macOS/Linux
python scripts/extract_subtitle.py   # re-downloads automatically

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/download_video.py (reported line 32)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/extract_subtitle.py (reported line 22)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/main.py (reported line 12)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/scrape_profile.py (reported line 33)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/storage.py (reported line 12)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/track_latest.py (reported line 38)May include surrounding context.

python
from dotenv import load_dotenv

BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")


def _default_output_dir() -> Path:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to generate and store Douyin session cookies locally in .douyin_cookies.json but does not warn that these cookies are effectively authentication secrets. If the file is exposed through weak filesystem permissions, backups, sync tools, or accidental commits, an attacker could hijack the user's logged-in Douyin session.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill instructs the agent to use shell commands, read and write files, and access environment-backed configuration, but it does not declare any tool scope or permissions boundaries. This increases the chance of over-broad execution in hosts that rely on manifest-level restrictions, especially because the skill performs scraping setup, cookie handling, and local file operations.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

The recommended use of pathlib.Path.home().rglob() recursively enumerates the user's home directory to locate the skill installation path. Broad filesystem discovery can reveal sensitive directory structure, consume excessive resources, and normalize an unnecessarily invasive pattern when the installation path could be passed explicitly or obtained from a safer known location.

Content

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

All commands must run from this skill's directory. To locate it, run:

bash
python -c "import pathlib; print([p for p in pathlib.Path.home().rglob('douyin-content-tracker-skill/SKILL.md')])"

Or check common locations:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill directs users to generate and persist Douyin login cookies in a local JSON file without any warning that these cookies are authentication material equivalent to a session token. If the file is exposed through weak permissions, backups, logs, or other tools, an attacker may be able to hijack the user's authenticated session and access or abuse the account.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The execution logging guide requires a specific Chinese output style, including Chinese step labels and example responses, but does not provide user opt-in or an alternative language option. This is a natural-language locale restriction that can violate organizational language-choice policy when not explicitly optional or justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation describes an automated pipeline that performs live network scraping, downloads media, invokes external tooling, and writes persistent artifacts to disk, but it does not clearly warn users before those actions occur. In a skill context, omission of these side effects can mislead users about privacy, bandwidth, storage, and compliance implications, increasing the chance of unintended data collection or system changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The reference indicates use of local cookie material via .douyin_cookies.json and adjacent environment configuration, but does not warn about the privacy and account-security implications of supplying authenticated session cookies for scraping. Users may expose active account tokens that could enable impersonation, tracking, or unintended access if the files are mishandled, logged, or shared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The markdown instructs users to delete the Whisper model file using del/rm in order to force a re-download, but it does not warn that this is a file-deletion step or advise users to verify the path before running it. Because markdown files should disclose behaviors that can affect user data or system integrity, this omission is a safety-warning gap.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script silently loads cookies from a local JSON file and injects them into a browser context for authenticated scraping. This is sensitive session material; if mishandled, stale, shared, or stolen cookies could enable unauthorized account access or scraping under another user's identity without clear operator awareness. The skill context increases concern because the whole workflow is built around evading platform friction and performing repeated authenticated collection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code calls Whisper with language="zh", which hard-codes a specific language for processing. Under the policy, forcing a language or locale without user opt-in is a natural-language policy violation unless the constraint is explicitly justified as region-specific, which is not shown here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.