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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.