Back to skill

Security audit

抖音账号诊断宗师

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly aligned with Douyin account diagnosis, but it embeds a shared API key and sends account identifiers and profile data to RedFox with incomplete user controls.

Review before installing. Only use this skill if you are comfortable sending target Douyin account identifiers to RedFox and redisplaying profile/content details in reports. Prefer configuring your own RedFox key through a protected environment or secret store, and avoid the embedded shared key and command-line key option. Treat report content and links as untrusted because they may include remotely sourced account text.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/douyin_diagnosis.py:22
Finding

Hardcoded Shared API Credential Embedded in the Skill

Content
View full analysis

Vulnerability Details

File Location: scripts/douyin_diagnosis.py, lines 22-33
Vulnerability Type: Hardcoded secret and plaintext credential exposure
Risk Level: High

Vulnerable Code

python
API_URL = "https://redfox.hk/story/api/dyUser/queryData"

# Skill source identifier (required on all API calls)
SOURCE = "Douyin Account Diagnosis-ClawHub"

# Built-in default key (used when the user has not configured an API key)
DEFAULT_API_KEY = "ak_1e449a28ae344cd1b7aa14ca481de8bb"


def resolve_api_key(cli_key=None):
    """Resolve API key: CLI argument > REDFOX_API_KEY environment variable > built-in key."""
    return cli_key or os.environ.get("REDFOX_API_KEY") or DEFAULT_API_KEY

Technical Analysis

A credential with the format of a live RedFox API key is committed directly to the source code and automatically selected whenever neither a command-line key nor REDFOX_API_KEY is supplied. Anyone who can download, inspect, mirror, or recover this package can extract and reuse the credential independently of the Skill.

The behavior also contradicts the security guidance in README.en.md, which explicitly states that API keys must not be hardcoded or exposed in plaintext. Because the fallback happens silently, users may unknowingly issue requests under a shared credential controlled by the Skill publisher rather than under a credential they configured.

HTTPS protects the credential while it is in transit, but it does not mitigate disclosure from the distributed source package. Rotation is also difficult because every installed copy contains the same secret.

Attack Path

  1. An attacker downloads or otherwise obtains the publicly distributed Skill package.
  2. The attacker reads scripts/douyin_diagnosis.py and extracts DEFAULT_API_KEY.
  3. The attacker sends arbitrary authenticated requests to the RedFox endpoint using the extracted key in the X-API-KEY header.
  4. Requests consume the ...[truncated 1213 chars]
Remediation
View remediation

Remediation Suggestions

  1. Immediately revoke and rotate the exposed API key through the RedFox control panel.
  2. Remove DEFAULT_API_KEY and eliminate the automatic shared-credential fallback.
  3. Require a key through a protected environment variable or a platform-managed secret store.
  4. Fail closed when no credential is configured, with a concise setup message.
  5. Do not place replacement credentials in source code, documentation, examples, generated reports, or version-control history.
  6. Rewrite repository history if the project has been published, while recognizing that history rewriting does not eliminate the need for revocation.
  7. Prefer per-user, narrowly scoped, revocable credentials with usage limits.
  8. Add automated secret scanning to CI and pre-commit checks.
  9. Align SKILL.md and references/core_workflow.md with the secure behavior; they currently advertise and prioritize the embedded fallback.
  10. Consider short-lived tokens or a brokered authorization flow if the service supports them.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/douyin_diagnosis.py:807
Finding

API Keys Accepted Through Command-Line Arguments and Partially Disclosed in Logs

Content
View full analysis

Vulnerability Details

File Location: scripts/douyin_diagnosis.py, lines 807-825
Vulnerability Type: Insecure credential handling through process arguments
Risk Level: Medium

Vulnerable Code

python
def main():
    args = sys.argv[1:]
    cli_key = None
    if "--api-key" in args:
        idx = args.index("--api-key")
        if idx + 1 < len(args):
            cli_key = args[idx + 1]
            args = args[:idx] + args[idx + 2:]
        else:
            print("[Error] The --api-key option requires a key value")
            sys.exit(1)

    if not args:
        print("Usage: python douyin_diagnosis.py <Douyin nickname or ID> [--api-key <API key>]")
        print("Example: python douyin_diagnosis.py ExampleAccount")
        print("Example: python douyin_diagnosis.py example_id")
        sys.exit(1)

    keyword = args[0]
    print(f"Querying Douyin account: {keyword} ...")

    acc = query_account(keyword, resolve_api_key(cli_key))

A second script also prints a credential prefix:

File Location: scripts/douyin_api_client.py, lines 406-411

python
if not api.api_key:
    print(f"API environment variable {DouyinUserAPI.ENV_VAR} is not set")
    print(f"Set it first: export {DouyinUserAPI.ENV_VAR}=your_api_key")
    exit(1)

print(f"API Key configured: {api.api_key[:8]}...")

Technical Analysis

Supplying secrets through command-line arguments exposes them to several operating-system and operational interfaces. Depending on the environment, command arguments may be visible in process listings, shell history, terminal capture, CI job metadata, audit logs, crash reports, or orchestration dashboards.

Removing the argument from the local Python list after startup does not remove it from the operating system's process metadata. The secret was already supplied in the process invocation.

The API client additionally prints the first ei ...[truncated 1278 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the --api-key option from normal usage.
  2. Read the key from REDFOX_API_KEY or, preferably, a platform-managed secret store.
  3. If interactive entry is required, use getpass.getpass() so the value is not echoed or placed in shell history.
  4. Never print any portion of the credential. Log only a boolean status such as API credentials configured.
  5. Redact authorization headers and key-like values in exception reporting and centralized logs.
  6. Update SKILL.md, usage messages, and workflow documentation so they no longer recommend command-line secret transmission.
  7. Rotate any keys that have already appeared in process logs, CI output, screenshots, or shell histories.

T01 · Skill Instruction Hijacking

Warning
Location
scripts/generate_diagnosis_report.py:360
Finding

Untrusted API Content Is Inserted into Agent-Facing Markdown Without Escaping

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_diagnosis_report.py, lines 360-409
Vulnerability Type: Markdown injection and indirect prompt-injection exposure
Risk Level: Medium

Vulnerable Code

python
return f"""## 📋 {nickname} - Douyin Account Diagnosis Report

### Basic Information

| Nickname | Douyin ID | Region | Followers | Likes | Works | RedFox Index | Data Time |
|----------|------------|--------|-----------|-------|-------|--------------|-----------|
| {nickname} | {account_id} | {location} | {follower_count} | {total_favorited} | {aweme_count} | {redfox_display} | {crawl_time} |

**Profile:** {sig_display}

---"""

# ...

rows = []
for i, w in enumerate(self.works, 1):
    title = (w.get("title") or w.get("desc") or "Untitled")[:20]
    create_time = w.get("createTime", "-")
    if create_time and len(create_time) > 16:
        create_time = create_time[:16]
    digg = format_number(w.get("diggCount", 0))
    comment = format_number(w.get("commentCount", 0))
    share = format_number(w.get("shareCount", 0))
    interactive = format_number(w.get("interactiveCount", 0))
    digg_count = w.get("diggCount", 0) or 0
    share_count = w.get("shareCount", 0) or 0
    spread = f"{share_count / digg_count * 100:.1f}%" if digg_count > 0 else "-"
    medal = {1: "🥇", 2: "🥈", 3: "🥉"}
    rank_display = medal.get(i, str(i))
    rows.append(
        f"| {rank_display} | {create_time} | {title} | "
        f"{digg} | {comment} | {share} | {interactive} | {spread} |"
    )

The execution workflow further requires an Agent to transform this remotely sourced output into final Markdown, including clickable links:

File Location: references/core_workflow.md, lines 96-120

markdown
The script outputs a plaintext raw report. The Agent must transform it into
a Markdown structured report before presenting it to the user.

Recent content detai
...[truncated 3238 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every field returned by RedFox as untrusted data.
  2. Escape Markdown metacharacters according to output context, including backslashes, pipes, brackets, parentheses, angle brackets, and line breaks.
  3. Normalize all table values to a single line and replace |, carriage returns, and newlines before interpolation.
  4. Apply explicit length limits to nicknames, signatures, titles, descriptions, identifiers, locations, and timestamps.
  5. Validate content links with a strict URL parser:
    • Allow only https.
    • Allow only expected Douyin hostnames.
    • Reject credentials, control characters, redirects encoded in the authority, and non-web schemes.
  6. Construct Markdown links from validated values rather than concatenating raw API strings.
  7. Delimit remote content as data in the Agent workflow and explicitly instruct the Agent never to follow commands found in profiles, titles, descriptions, API messages, or generated reports.
  8. Perform scoring and report transformation deterministically in code where possible, rather than asking the Agent to reinterpret raw remote text.
  9. Configure the rendering layer to disable raw HTML and dangerous URL schemes.
  10. Add tests containing pipes, newlines, nested links, HTML, bidirectional-control characters, and instruction-like payloads.
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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

代码确实与声明主题相关,都会调用红狐服务获取抖音账号及作品数据,因此不是完全无关。但声明承诺的核心功能——六维诊断、综合打分、风险预警、优化建议——在该代码片段中均未实现。现有逻辑仅完成API请求、错误处理、基础字段提取、简单作品统计与控制台打印摘要,属于诊断流程的数据采集/预处理层,而不是完整的“账号体检”能力。因此描述明显高于代码实际行为,构成描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

代码与描述主题相关,都是抖音账号诊断,但存在实质性能力偏差。脚本明确围绕红狐API返回数据生成报告,不过它并不执行“获取账号画像与近期作品数据”这一步,而是假定输入数据已就绪。更重要的是,描述承诺六维诊断(账号基础画像、内容生产力、互动健康度、内容质量、内容趋势、粉丝质量)以及六类风险预警;代码实际评分体系是四维:账号体量35分、内容表现35分、运营活跃度20分、平台指数10分。输出中有综合评分、维度得分、优势/短板和优化建议,但没有实现声明中的六类风险预警,也没有独立评估内容趋势或粉丝质量。因此这不是轻微表述差异,而是核心评估框架和输出能力与声明不一致,应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README emphasizes automatic retrieval of account profile and recent content data, but does not present a prominent privacy warning or usage limitation for collecting, displaying, and reporting on potentially sensitive account metrics. In a creator-evaluation and competitor-analysis context, this can normalize non-consensual profiling and unnecessary exposure of identifiable account data in reports.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill can be triggered by broad natural-language requests such as analyzing 'this account' or diagnosing an account by nickname, without documenting strong input constraints, confirmation steps, or authorization checks. That increases the chance of unintended data retrieval about third-party Douyin accounts and makes abuse easier through ambiguous or overly broad user prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README emphasizes automatic retrieval of account profiles and recent works but does not warn users about privacy, consent, retention, or third-party data handling implications. Even if the data is publicly accessible, automated aggregation, scoring, and risk labeling can create privacy and profiling concerns, especially when analyzing accounts belonging to other individuals.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill advertises broad natural-language triggers such as '分析这个抖音号' and '查看XX抖音数据', which can cause unintended invocation on loosely related user requests. Because the skill performs automatic external data retrieval and account analysis, overbroad activation increases the risk of processing third-party account data without clear user intent or sufficient confirmation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
79% confidence
Finding

The skill advertises external service use, optional API-key configuration, and installation into agent skill directories, but does not declare any explicit tool scope or permissions boundaries. In a skill ecosystem, undeclared network, environment-variable, or file-write expectations reduce transparency and can cause the host agent to grant broader capabilities than users expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases include broad natural-language expressions such as requests to '查看XX抖音数据' or '分析这个抖音号', which increases the chance of accidental invocation. In context, accidental activation may send account identifiers to an external service or produce unintended data lookups without clear user intent, creating privacy and consent concerns.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description does not clearly warn that provided account names/IDs will be transmitted to a third-party Redfox service and that returned output may include clickable links to recent works. This weakens informed consent and can expose third-party account data, browsing targets, or user-supplied identifiers to an external provider unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The API documentation explicitly describes collecting and returning privacy-sensitive profile data such as UID, province/city, IP属地, gender, age, avatar URL, and recent works, but it provides no warning, consent requirements, retention limits, or access-control expectations. In the context of an account-diagnosis skill, this increases the risk of unauthorized profiling, privacy-law noncompliance, and misuse of personal data beyond what is necessary for diagnostics.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The workflow explicitly permits falling back to a built-in default API key when neither a user-supplied key nor an environment key is present. Embedding shared credentials in a distributable skill creates a secret exposure and abuse risk: any user or downstream agent execution could consume the owner’s quota, access paid services without authorization, or leak the key through logs, errors, or repository disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow sends account identifiers such as nicknames or account IDs to an external service (redfox.hk) as part of diagnosis, but does not warn the user that their input will be transmitted to a third party. This lack of transparency can violate user expectations, privacy requirements, or enterprise data handling policies, particularly when identifiers may correspond to real persons or monitored accounts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The workflow collects and presents detailed profile data including UID, region, IP location, gender, age, avatar, and biography, but provides no user-facing notice, consent flow, or data minimization guidance. Even if sourced from a third-party API, aggregating and redisplaying this personal data increases privacy risk, especially for non-obvious fields like IP属地, age, and gender.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This is a real external-transmission behavior: the skill posts user-provided account identifiers/names and a source tag to an external domain. In the context of an account-diagnosis skill, outbound transmission is expected functionally, but it is still security-relevant because it shares user-supplied data with a third party and the manifest does not clearly communicate that data flow.

Content

Scanner excerpt · scripts/douyin_api_client.py (reported line 80)May include surrounding context.

python
}

        try:
            response = requests.post(url, json=payload, headers=self.headers, timeout=30)
            result = response.json()

            code = result.get("code")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script transmits user-supplied Douyin account identifiers and names to a third-party external service without any explicit user consent, privacy notice, or minimization controls. Even if the identifiers are public-facing handles, sending them off-platform can create privacy, profiling, and compliance concerns, especially in a diagnosis skill that users may assume operates locally or only within the described product boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script sends a user-supplied Douyin nickname/account ID plus a source tag to a third-party RedFox API without any explicit user notice or consent mechanism. This creates a real privacy and data-sharing risk because identifiers entered by the user are transmitted off-platform to an external service, and the source metadata can further reveal the originating skill or workflow.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring states the report is based on a four-dimension evaluation system, and the scoring/output code consistently computes only 账号体量、内容表现、运营活跃度、平台指数. The manifest, however, promises six dimensions including 互动健康度、内容质量、内容趋势、粉丝质量, so the implemented behavior does not match the advertised diagnostic scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module description and many output strings indicate the skill generates a fixed Chinese-language diagnosis report, with no opt-in or configurable locale selection. Under the policy, forcing a specific language without user choice can be a natural-language locale violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The generated report includes a comprehensive score section with strengths and weaknesses plus an optimization section, but there is no implementation of six distinct risk warning categories as described in the manifest. This is a semantic mismatch in the actual report contents versus the skill’s claimed outputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

All user-facing instructions, examples, and output descriptions are presented only in Chinese, and the skill does not state whether other languages are supported or require user opt-in to a Chinese-only experience. This can violate language/locale policy when a skill implicitly enforces one language without choice or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

SQP-3 applies to all file types and flags language-policy issues when a skill forces a specific language without user opt-in. This file presents all instructions, parameters, and error outputs only in Chinese, with no indication that the locale restriction is optional or required for a region-specific audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This markdown file presents all skill content, labels, and instructions exclusively in Chinese. Under the policy rule for language or locale constraints, forcing a specific language without offering user choice or documenting the constraint can be considered a natural-language policy violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes a Douyin account diagnosis skill that analyzes account and content data, but it does not mention accessing runtime secrets or environment-based credential retrieval. While calling the external Redfox service is expected for this purpose, directly reading an API key from process environment is an additional capability beyond the stated end-user function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code accesses a sensitive API key from the REDFOX_API_KEY environment variable and uses it in request headers. While the variable name is documented, there is no cautionary note advising users that the script depends on a secret credential and will transmit it to an external service for authentication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The manifest says the skill performs diagnosis based on the Redfox data service, but the code’s returned contract explicitly signals 'fallback_needed' for degrading to network search when the API is unavailable. That changes the implied data source and operational behavior from a single declared provider to conditional alternate retrieval.

Content

No source excerpt is available for this finding.