Back to skill

Security audit

Douyin Search

Security checks for vulnerabilities and agentic risk

Overview

This Douyin search skill can silently reuse an existing browser login profile and runs remote web content with reduced browser isolation, so it needs review before use.

Install only if you are comfortable with Douyin browser automation and persistent cookies. Before use, remove or require explicit consent for the OpenClaw profile fallback, avoid running it as root, remove --no-sandbox where possible, and use pinned dependencies.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/douyin_search.py:178
Finding

Silent Reuse of an External Privileged Browser Profile

Content
View full analysis

Vulnerability Details

File Location: scripts/douyin_search.py, lines 24 and 178–182
Vulnerability Type: Unauthorized access to an unrelated authenticated browser profile
Risk Level: High

Vulnerable Code:

python
OPENCLAW_PROFILE = "/root/.openclaw/browser/openclaw/user-data"
python
# Step 2: Try with OpenClaw browser profile
if os.path.exists(OPENCLAW_PROFILE):
    result2 = search_with_playwright(keyword, count, profile_dir=OPENCLAW_PROFILE)
    if result2["count"] > 0:
        return result2

Technical Analysis

When a search using the skill-specific profile does not return results, the script automatically checks for and opens the external profile at /root/.openclaw/browser/openclaw/user-data. A browser profile can contain authenticated cookies, session tokens, browsing state, local storage, and other sensitive data belonging to services outside this skill.

The fallback occurs automatically and does not require an explicit command-line option or informed user approval. It therefore crosses the least-privilege boundary represented by the skill’s documented .browser-profile/ directory. The use of a path under /root further indicates that the accessed state may belong to a privileged execution context.

The code does not directly export profile contents, and no credential-exfiltration mechanism was found. Nevertheless, opening the external profile makes its authenticated state available to the browser context and to pages loaded in that context. Directly opening a shared profile may also conflict with another running browser process or corrupt profile data.

Attack Path

  1. The user invokes a normal Douyin search.
  2. The script searches using its own .browser-profile/.
  3. The first search returns no results.
  4. The script detects /root/.openclaw/browser/openclaw/user-data.
  5. Without requesting consent, it launches a persistent Chromium context using that exte ...[truncated 932 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the automatic OPENCLAW_PROFILE fallback and restrict the skill to its dedicated .browser-profile/ directory.
  • If external profile reuse is required, place it behind an explicit command-line option that is disabled by default.
  • Obtain informed user consent before accessing any profile not created by this skill.
  • Validate configured profile paths and reject system, root-owned, shared, or unrelated browser profiles by default.
  • Do not directly open a profile that may be used by another browser process.
  • Prefer a dedicated least-privilege profile containing only the minimum Douyin authentication state.
  • Run the skill under an unprivileged service account and enforce filesystem permissions preventing access to unrelated profiles.
  • Clearly document what browser state is accessed, how long it is retained, and how users can delete or revoke it.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/douyin_search.py:57
Finding

Chromium Sandbox Disabled While Rendering Remote Content

Content
View full analysis

Vulnerability Details

File Location: scripts/douyin_search.py, lines 57–70 and 203–210
Vulnerability Type: Browser isolation disabled for untrusted remote content
Risk Level: Medium

Vulnerable Code:

python
with sync_playwright() as p:
    try:
        context = p.chromium.launch_persistent_context(
            use_dir,
            headless=True,
            args=["--no-sandbox", "--disable-blink-features=AutomationControlled"],
            user_agent=(
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/125.0.0.0 Safari/537.36"
            ),
            viewport={"width": 1280, "height": 900},
            locale="zh-CN",
        )
python
with sync_playwright() as p:
    context = p.chromium.launch_persistent_context(
        PROFILE_DIR,
        headless=False,
        args=["--no-sandbox"],
        viewport={"width": 1280, "height": 900},
        locale="zh-CN",
    )

Technical Analysis

Both browser launch paths pass Chromium’s --no-sandbox option. The browser sandbox is a defense-in-depth control that restricts compromised renderer processes and reduces their ability to access the host filesystem, process namespace, and user privileges.

The script loads and executes remote Douyin web content in these browser contexts. If that content, a third-party resource, or the installed Chromium build exploits a browser vulnerability, disabling the sandbox removes a major containment boundary. The risk is amplified when the script runs with elevated privileges, as suggested by its hard-coded reference to a profile under /root.

No browser exploit is included in the project, so exploitation depends on a separate Chromium or browser-component vulnerability. The insecure launch configuration nevertheless increases the impact of such a vulnerability.

Attack Path

...[truncated 1047 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove --no-sandbox from both persistent-context launch configurations.
  • Run Chromium as a dedicated, unprivileged operating-system user for which the normal Chromium sandbox is supported.
  • Avoid running the skill or browser as root.
  • Apply filesystem restrictions so the browser account can access only the skill-specific profile and required temporary directories.
  • Keep Playwright and its managed Chromium revision patched and tested.
  • Use additional host isolation, such as a locked-down container, seccomp profile, read-only filesystem, and restricted network policy, as defense in depth.
  • Fail safely rather than automatically disabling the sandbox when the execution environment is incompatible with it.

T08 · Insecure Dependencies

Note
Location
README.md:11
Finding

Unpinned Runtime Package and Browser Installation

Content
View full analysis

Vulnerability Details

File Location: README.md, lines 11–15
Vulnerability Type: Non-reproducible third-party dependency installation
Risk Level: Low

Vulnerable Code:

bash
pip install playwright
playwright install chromium

Technical Analysis

The installation instructions retrieve the current Playwright package and its associated Chromium build without an exact version pin, lockfile, package hash, or documented artifact-integrity policy. Consequently, installations performed at different times may execute materially different third-party code from the code originally audited.

The main script also imports httpx, but the documented installation procedure does not declare or pin that dependency. Users may install it manually or rely on an environment-provided version, further reducing reproducibility.

No evidence of dependency confusion, typosquatting, a malicious package, or an intentionally unsafe package source was found. This finding concerns supply-chain hardening and exposure to future upstream compromise or incompatible releases.

Attack Path

  1. A user follows the installation instructions.
  2. pip resolves the latest available Playwright release from its configured package index.
  3. playwright install chromium downloads the browser revision selected by that Playwright release.
  4. If an upstream account, package index, distribution artifact, or dependency is compromised, the altered code is installed.
  5. The downloaded package or browser executes with the privileges of the installing or running user.

Impact Assessment

Impact depends on the compromised component and installation privileges. A malicious Python package could execute during installation or import, while a compromised browser binary could execute whenever the skill searches or performs login.

Under a normal user account, accessible user files, environment data, and browser state could be affected. Insta ...[truncated 202 chars]

Remediation
View remediation

Remediation Suggestions

  • Provide a dependency manifest that pins exact versions of both playwright and httpx.
  • Use a lockfile or hash-checked requirements file, such as pip install --require-hashes -r requirements.txt.
  • Document the expected Playwright-managed Chromium revision and update it through a controlled review process.
  • Install dependencies only from explicitly configured trusted indexes over TLS.
  • Generate and retain software bills of materials and dependency-scan results for released skill versions.
  • Run dependency updates through automated security testing before publishing them.
  • Perform installation in an isolated virtual environment under an unprivileged account.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description frames the skill as a simple search helper, but the body reveals materially more sensitive behavior: opening a browser for QR-code login, persisting browser profile data, and reusing authenticated sessions from local profile storage. This mismatch can mislead reviewers and users about credential/session handling, creating risk of unintended account access, session leakage, or use of preexisting authenticated state without clear consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The search flow automatically checks for the existence of another application's persisted browser profile and uses it to perform authenticated searches. This creates an implicit credential-sharing path, allowing the skill to act with someone else's logged-in session and potentially expose private account capabilities or data.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README defines very broad natural-language triggers such as '搜索一下海鲜视频' and '帮我找抖音上的猫咪视频', which closely resemble ordinary user requests. In an agent environment, this can cause overbroad or unintended skill activation, leading the agent to invoke browser automation and use persisted login state when the user may only be making a general request rather than explicitly consenting to this specific skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly instructs use of external networked resources (Douyin website and suggestion API) but declares no tool or permission scope. That omission weakens reviewability and policy enforcement because an agent may invoke network-capable actions without clear, least-privilege declarations. In a scraping/login-oriented skill, undeclared network use is especially relevant because it reaches third-party services and may handle authenticated sessions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The natural-language activation instructions emphasize flexible extraction but do not define boundaries or disambiguation rules, so the agent may infer a Douyin search from vague content-seeking requests. In this skill, that is more dangerous because activation can lead to browser automation, external requests, and possible reuse of stored authenticated state.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation guidance is broad enough to trigger on generic 'find' or 'browse' requests, which increases the chance the agent will route unrelated user intents into this networked scraping skill. Over-broad activation can cause unexpected browsing, third-party requests, or login prompts in contexts where the user did not specifically ask to use Douyin.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script defines and later uses an external browser profile path belonging to another application (/root/.openclaw/...) to inherit persisted authentication state. Reusing another app's browser data exceeds the stated purpose of a Douyin search skill and can access cookies, sessions, and other sensitive browsing artifacts without explicit user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script is configured to reuse a persisted external browser profile without any user-facing warning, consent prompt, or disclosure. Even if intended as a convenience fallback, silently inheriting existing login state undermines user expectations and can lead to unauthorized use of stored sessions.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
84% confidence
Finding

Using page.wait_for_event("close", timeout=0) waits indefinitely for the browser window to close, allowing the process to hang without bound. In an agent or automation environment, this can tie up workers or resources and be abused for denial-of-service by causing the task to never complete.

Content

Scanner excerpt · scripts/douyin_search.py (reported line 214)May include surrounding context.

python
page = context.new_page()
        page.goto("https://www.douyin.com", timeout=30000)
        try:
            page.wait_for_event("close", timeout=0)
        except Exception:
            pass
        context.close()

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code returns user-facing messages in Chinese string literals, which enforces a specific language regardless of user preference. The file does not indicate that the skill is intentionally limited to a Chinese-speaking or region-specific audience, nor does it provide opt-in or fallback behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes generic phrases such as '搜索一下', '抖音上的', and '帮我找抖音' that can plausibly appear in normal conversation, increasing the chance the skill is invoked when the user did not explicitly intend to use it. Because this skill performs external search behavior and may leverage persisted login state, accidental invocation could cause unintended queries or disclose browsing-derived results in a context the user did not expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

Line L03 states '用自然语言就行' in Chinese, and the invocation examples and instructions are presented as Chinese-first usage without any note that users may choose another language or that the skill is intentionally locale-specific. Under the policy, forcing or implying a fixed language without user opt-in can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The example output presents the login prompt only in Chinese, and the file overall centers Chinese responses even when the user query is in English. This suggests a locale/language constraint without explicit user opt-in or a documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The Playwright browser context is hard-coded with locale="zh-CN", which imposes a specific language/locale behavior. The file does not offer a user opt-in or configurable locale, and there is no documented policy justification that this skill must operate only in Chinese locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The headed login browser context also sets locale="zh-CN", forcing a specific locale during user interaction. Because the user is not given a choice and no region-specific justification is stated, this is a natural-language policy concern under the locale rule.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.