Back to skill

Security audit

douyin-creator-insight

Security checks for vulnerabilities and agentic risk

Overview

The skill is largely aligned with public Douyin creator reporting, but it needs review because it can reuse logged-in browser profiles and send media plus API credentials to configurable external transcription services.

Install only if you are comfortable giving the skill access to a logged-in Douyin browser profile and to public creator/video metadata. Prefer a dedicated browser profile, avoid sharing a favorites profile unless intentional, keep API keys in a trusted secret store, do not set custom ASR endpoint environment variables unless you trust the host, and use index mode when you do not want media downloaded or sent to ASR providers.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
raise ValueError("adapter must use module:function format")
    module_name, function_name = spec.rsplit(":", 1)
    module = importlib.import_module(module_name)
    adapter = getattr(module, function_name, None)
    if not callable(adapter):
        raise ValueError(f"adapter is not callable: {spec}")
    return adapter
Confidence
90% confidence
Finding
The adapter loader imports an arbitrary module and resolves an arbitrary attribute from a user-supplied `module:function` string, then later invokes it as trusted code. In a skill/agent context, this is effectively unrestricted code execution if an attacker can influence CLI arguments or configuration, because importing a module can also trigger malicious import-time side effects.

Tainted flow: 'request' from os.environ.get (line 456, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
"Accept": "*/*",
        },
    )
    with urlopen(request, timeout=180) as response, destination.open("wb") as output:
        while chunk := response.read(1024 * 1024):
            output.write(chunk)
Confidence
92% confidence
Finding
_download_media fetches an arbitrary URL from video.video_url using urlopen with no host allowlist, scheme restriction, or IP-range validation. If an attacker can influence Video metadata, this becomes SSRF and can be used to reach internal services or unexpected endpoints, especially because the code adds trusted-looking browser headers.

Tainted flow: 'request' from os.environ.get (line 456, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(request, timeout=120) as response:
            response_payload = json.loads(response.read().decode("utf-8"))
    except HTTPError as exc:
        detail = exc.read().decode("utf-8", errors="replace")[:500]
Confidence
87% confidence
Finding
The request target is configurable through DOUYIN_CLOUD_ASR_URL, so a compromised or unsafe runtime environment can redirect audio transcription requests and API credentials to an arbitrary server. That is a real exfiltration and trust-boundary issue, though it depends on environment control rather than direct user input.

Tainted flow: 'request' from os.environ.get (line 456, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(request, timeout=180) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as exc:
        detail = exc.read().decode("utf-8", errors="replace")[:500]
Confidence
90% confidence
Finding
_post_multipart posts extracted audio and the Authorization bearer token to an endpoint taken from SILICONFLOW_ASR_URL without validating that the host is trusted. If that environment variable is altered, sensitive content and credentials can be exfiltrated to an attacker-controlled service.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares and instructs use of sensitive capabilities including environment-variable access, filesystem read/write, shell execution, and network access, but there is no explicit permissions declaration to constrain or document those powers. In a skill that handles browser profiles, API keys, local output paths, and media downloads, this mismatch increases the risk of over-privileged execution, accidental secret exposure, or unsafe operator trust because reviewers and runtime policy cannot easily validate least privilege.

Intent-Code Divergence

High
Confidence
96% confidence
Finding
The module docstring claims cloud ASR never downloads media locally, but the SiliconFlow upload path explicitly downloads source media to a temporary directory and extracts audio before upload. This is a security-relevant documentation mismatch because operators may rely on the claim when assessing data handling and privacy exposure.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The collector explicitly searches for and reuses browser profile directories from a different skill (`douyin-favorites-to-knowledge`), which expands accessible data beyond this skill’s stated purpose of analyzing public creator profiles. Reusing an unrelated persistent authenticated profile can expose saved cookies, session state, and historical browsing context from another workflow, creating cross-skill data leakage and scope creep even if the code only intends to fetch public data.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The loader imports DOUYIN_FAVORITES_PROFILE_DIR even though the skill is described as analyzing public creator content, which expands the runtime scope into favorites/profile data handling. That mismatch can enable unintended access to a more sensitive browser/profile context than users would expect, increasing the chance of privacy boundary violations if other parts of the skill consume that variable.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The docstring says the helper is only for cloud ASR and shared browser profile support, but the code also loads a favorites-profile setting. This documentation/code mismatch is security-relevant because it hides the true data access surface from reviewers and operators, making misuse of a more privileged profile more likely.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The setup helper enumerates config files, skill roots, and browser-profile directories belonging to other Douyin-related skills, then reuses those artifacts to determine installation state and available shared profiles. This creates an unnecessary cross-skill data boundary violation: even without reading secrets directly, it reveals presence, paths, and potentially session-bearing browser profile locations from unrelated tooling, which exceeds the stated analytics-only scope and increases privacy and misuse risk.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The function opens a referral signup URL in the user's default browser, which is unrelated to the core task of analyzing public creator content. Triggering external promotional navigation from a skill introduces trust and consent concerns, and in an agent context can unexpectedly drive user actions outside the tool's stated purpose.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The code depends on third-party Apify actors to retrieve transcripts, extending data processing to external services that are not clearly justified or constrained in the skill contract. This creates supply-chain and data-governance risk because actor behavior, logging, retention, and output integrity are outside the developer's direct control.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The document recommends sending Douyin video URLs and profile data to third-party Apify actors for transcript extraction and fallback web rendering, but it does not warn about privacy, data handling, retention, or consent implications. Even though the skill is framed around public creators, transcript text, engagement metadata, and rendered profile data are still transmitted to external services, which can create compliance and privacy risks if users are not clearly informed.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The playbook directs the agent to automatically send user-provided creator queries to a third-party search/browser tool, but it does not require notice or consent before disclosure. Even if the input is usually a public nickname, users may submit identifying or sensitive query terms, creating an avoidable privacy and data-sharing risk through external transmission.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The playbook tells users to upload raw JSON or provide manual data as a fallback, but it gives no warning to review that data for personal, account, or embedded metadata before sharing. Even though the skill targets public Douyin creator analysis, exported raw datasets can still contain identifiers, cookies-adjacent fields, URLs, or other sensitive metadata that may be unnecessarily collected, stored, or exposed.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The diagnostic checklist says to check whether the Apify token is valid, but does not warn against exposing the token in logs, prompts, screenshots, or output files. In an operational troubleshooting context, users may paste credentials into shared channels or debugging artifacts, creating a realistic risk of credential leakage.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The code creates or reuses a persistent browser profile directory automatically, which preserves authentication material and browsing state across runs without any warning or consent mechanism in this file. In a skill that uses authenticated browser context, silent persistence increases the risk of unintended retention, cross-run correlation, and later access to user account state by other workflows using the same directory.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The module sends video URLs and processing requests to external Apify actors without any visible consent, notice, or configurable disclosure mechanism in this code path. Even if the target videos are public, this external sharing can violate user expectations, internal data-handling requirements, or platform compliance obligations.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
tests/test_runtime_env.py:50