Back to skill

Security audit

Fast Douyin Publish

Security checks for vulnerabilities and agentic risk

Overview

This Douyin publishing skill mostly does what it says, but it needs review because it stores reusable login sessions in plaintext and has scope/documentation mismatches.

Review before installing. Use it only from a private, isolated workspace, protect or delete config/cookies/douyin.json after use, do not commit config/cookies, config/accounts.json, publish logs, or error_debug.png, and remove the unused non-Douyin account entries unless you intentionally need them. Avoid headless publishing until you have verified exactly what video and metadata will be posted.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auto_publisher.py:49
Finding
Authentication session state is stored in plaintext without restrictive permissions## Vulnerability Details **File Location**: `scripts/auto_publisher.py:49-60`, with session restoration at `scripts/auto_publisher.py:106-122` **Vulnerability Type**: Plaintext storage of sensitive authentication data **Risk Level**: Medium ### Vulnerable Code ```python def load_cookies(self, platform: str) -> Optional[dict]: """Load cookies for the specified platform.""" cookies_path = self.get_cookies_path(platform) if cookies_path.exists(): return cookies_path return None def save_cookies(self, platform: str): """Save cookies from the current session.""" if self.context: cookies_path = self.get_cookies_path(platform) self.context.storage_state(path=str(cookies_path)) print(f"Saved {platform} login state") ``` The saved state is subsequently restored into a new browser context: ```python if platform: cookies_path = self.load_cookies(platform) if cookies_path: with open(cookies_path, 'r', encoding='utf-8') as f: storage_data = json.load(f) if "cookies" in storage_data: for cookie in storage_data["cookies"]: if cookie.get("sameSite") not in ["Strict", "Lax", "None"]: cookie["sameSite"] = "Lax" context_options["storage_state"] = storage_data ``` ### Technical Analysis Playwright storage-state files can contain authenticated session cookies and origin storage. The code writes this data to `config/cookies/douyin.json` as plaintext through `context.storage_state()`. The implementation does not explicitly apply owner-only file permissions, encrypt the state, verify file ownership before loading it, or prevent the cookie directory from being committed, archived, or copied. File permissions therefore depend entirely on the process environment and its default `umask`. A party that obtains this file may be able to restore the captured state in an ...[truncated 1322 chars]
Remediation
## Remediation Suggestions 1. Prefer an operating-system credential store or protected secret-management facility for persistent session material. 2. If a file must be used, create it with owner-only permissions such as `0600` and create `config/cookies/` with restrictive directory permissions such as `0700`. 3. Write through a securely created temporary file, set its permissions before adding sensitive content, and atomically replace the destination. 4. Verify that the state file is a regular file owned by the expected user and is not a symbolic link before loading it. 5. Add `config/cookies/`, storage-state files, publication logs, and debug artifacts to `.gitignore` and backup-exclusion rules. 6. Avoid storing account passwords in `config/accounts.json`; remove unused credential fields or retrieve secrets from a credential manager. 7. Document session revocation and deletion procedures and provide a command that securely removes saved browser state. 8. Warn users that copying the project directory may copy an authenticated session.

T08 · Insecure Dependencies

Note
Location
SKILL.md:27
Finding
Dependency and browser installation instructions are not version-pinned## Vulnerability Details **File Location**: `SKILL.md:27-30` **Vulnerability Type**: Unpinned executable third-party dependency **Risk Level**: Low ### Vulnerable Code ```bash pip install playwright playwright install chromium ``` Equivalent unpinned installation instructions also appear in `README.md`. ### Technical Analysis The installation procedure resolves the current Playwright package version from the configured Python package index and then downloads the Chromium revision selected by that package. The project provides no dependency lockfile, exact version constraint, package hashes, or documented expected browser revision. No typographical package-name error, untrusted package index, or known malicious dependency was observed. The risk arises from non-reproducible dependency resolution: the code installed in the future may differ from the version originally reviewed. A compromised upstream release, compromised configured package index, or unexpectedly incompatible update could therefore affect users who follow these instructions. ### Attack Path 1. A user follows the documented installation instructions. 2. `pip` resolves `playwright` dynamically from the user's configured package source. 3. The installed Playwright version determines and downloads a corresponding Chromium build. 4. If the resolved package, package source, or downloaded browser artifact has been compromised, attacker-controlled code executes during installation or subsequent browser automation. 5. That code runs with the privileges of the user executing the installation or publisher script and can access data available to that account, including local publication files and browser session state. ### Impact Assessment In a successful supply-chain compromise, malicious dependency code could execute with the installing user's privileges. This could expose local files and authentication state, modify project data, or perform network activity ...[truncated 257 chars]
Remediation
## Remediation Suggestions 1. Pin Playwright to a reviewed exact version, for example through `requirements.txt` or `pyproject.toml`. 2. Generate and commit a lockfile that records transitive dependency versions. 3. Use hash-verified installation, such as `pip install --require-hashes -r requirements.txt`, where practical. 4. Document the expected Playwright-managed Chromium revision and update it through a controlled review process. 5. Require a trusted package index and avoid inheriting unreviewed global index or mirror configuration. 6. Run dependency installation and browser automation as an unprivileged user in an isolated virtual environment or container. 7. Add automated dependency vulnerability scanning and review version changes before updating the lockfile.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared purpose does not accurately match the documented or detected behavior: it claims automatic copy/tag optimization that appears unimplemented, while under-disclosing persistent storage of login cookies and publish history. Misleading capability and data-handling descriptions can cause users to authorize automation without informed consent, especially for a skill that stores reusable authentication state.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill is presented as a Douyin-only publishing assistant, but the configuration enables additional platforms including WeChat Channels, Xiaohongshu, Bilibili, and YouTube. This expands the operational scope beyond the declared functionality and could lead to unexpected credential collection, cross-platform posting, or unauthorized access paths if a user installs the skill expecting only Douyin behavior.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README states that login cookies are saved for reuse, but does not warn that these session artifacts are sensitive credentials that can grant account access if copied or exposed. In a browser automation skill for publishing to a social media account, stolen cookies could enable unauthorized posting or account takeover until the session expires.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill describes behavior that reads environment/state and writes local files (account config, cookies, publish logs) but does not declare any explicit tool scope or permissions. This weakens least-privilege controls and makes it harder for users or a hosting platform to understand and constrain what data the skill can access or persist.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill persists publish history and login session cookies locally without a clear up-front warning in the main description or usage flow. Stored session cookies can enable account takeover if the local machine or files are exposed, and publish logs may leak sensitive operational metadata about the user's activity.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
User-facing descriptions, prompts, and CLI help are presented exclusively in Chinese, which effectively forces a specific language without opt-in. The file does not indicate that the tool is intentionally restricted to a Chinese-speaking or region-specific audience.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script persists authenticated browser session state to config/cookies/douyin.json without any explicit warning, consent flow, or file-permission hardening. If the local system is shared, backed up insecurely, or the project directory is exposed, an attacker may reuse the stored session to access the Douyin account without re-authentication.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The manifest description says the skill supports automatic caption generation and tag optimization, but this file only publishes a video using CLI-provided --title, --tags, and optional --description. There is no model call, heuristic generation, or tag-optimization routine anywhere in the implementation, so the advertised functionality does not match the actual behavior.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script automatically uploads a local video plus user-supplied title, tags, and description to Douyin once invoked, but it does not present an explicit transmission/privacy warning or confirmation step at the point of publishing. In an automation context, this increases the risk of unintended disclosure of sensitive media or metadata to a third-party platform.

Natural-Language Policy Violations

Low
Confidence
70% confidence
Finding
The README presents all instructions, commands, and user-facing guidance only in Chinese, which can amount to an implicit language constraint. There is no indication that the skill supports language choice or that the Chinese-only presentation is a justified region-specific requirement.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
Line L039 states that `--title` and `--tags` are mandatory, but in the same sentence says that if the user does not provide them, the skill should automatically generate them. This is an active contradiction in the documentation about the intended behavior of the publishing interface.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The skill description and invocation examples are presented only in Chinese, and the trigger section lists only Chinese phrases. This imposes a specific language/locale for activation and use without documenting that the skill is intentionally region-specific or offering user opt-in or alternatives.

Static analysis

No suspicious patterns detected.