Back to skill

Security audit

mar-douyin-hot-trend

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly fetches public Douyin trend data, but it also includes under-disclosed automation scripts with unsafe command execution and a hard-coded Telegram recipient payload.

Review before installing. Use only if you trust the SkillBoss/HeyBoss API service with the provided SKILLBOSS_API_KEY, avoid invoking scripts/get-hot-trend.js with untrusted arguments, and remove or reconfigure the hard-coded Telegram chat_id before any automation consumes daily-hot-trend-output.json.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get-hot-trend.js:13
Finding

Shell Command Injection Through Unvalidated CLI Argument

Content
View full analysis

Vulnerability Details

File Location: scripts/get-hot-trend.js, lines 13-18 and 72-74
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
function getHotTrend(limit = 10) {
  try {
    const scriptPath = path.join(__dirname, 'douyin.js');
    const output = execSync(`node "${scriptPath}" hot ${limit}`, {
      encoding: 'utf-8',
      cwd: path.dirname(scriptPath)
    });
    return output;
js
async function main() {
  const limit = process.argv[2] || 10;
  
  console.log('开始获取抖音热榜...');
  const hotTrendData = getHotTrend(limit);

Technical Analysis

The limit value originates directly from process.argv[2] and is interpolated into a command string passed to child_process.execSync. This API executes the supplied string through a system shell.

The argument is neither converted to a number nor validated against an allowlist or numeric range. Consequently, shell metacharacters contained in the CLI argument are interpreted as command syntax rather than as part of the intended item limit.

Although the normal use case supplies a number such as 10, any user, scheduler, or integration capable of controlling this argument can append an arbitrary operating-system command.

Attack Path

  1. An attacker obtains the ability to invoke scripts/get-hot-trend.js or influence the argument supplied by an automation system.
  2. The attacker provides an argument containing shell syntax, such as 10; id.
  3. main() stores the complete string in limit.
  4. getHotTrend() constructs a command equivalent to:
text
node "/project/scripts/douyin.js" hot 10; id
  1. execSync passes the string to the system shell.
  2. The intended Node.js command runs, followed by the injected command.
  3. The injected process executes with the same operating-system identity and permissions as the Skill process.

Impact Assessment

Successful exploitation permits arbitrary local c ...[truncated 661 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace shell-based execSync with execFileSync or spawnSync, passing every argument separately:
js
const { execFileSync } = require('child_process');

function getHotTrend(limit = 10) {
  const scriptPath = path.join(__dirname, 'douyin.js');
  return execFileSync(
    process.execPath,
    [scriptPath, 'hot', String(limit)],
    {
      encoding: 'utf-8',
      cwd: path.dirname(scriptPath),
      timeout: 30_000
    }
  );
}
  1. Parse and validate the CLI value before using it:
js
const requestedLimit = Number.parseInt(process.argv[2] ?? '10', 10);

if (!Number.isInteger(requestedLimit) ||
    requestedLimit < 1 ||
    requestedLimit > 50) {
  throw new Error('Limit must be an integer between 1 and 50');
}
  1. Do not attempt to make shell interpolation safe through partial escaping. Avoid invoking a shell entirely when executing a fixed program.
  2. Apply a timeout and output-size controls to prevent the child process from hanging or exhausting resources.
  3. Run the Skill under a dedicated, least-privileged operating-system account without access to unrelated files or credentials.
  4. Add tests using shell metacharacters to verify that malformed values are rejected and never interpreted by a shell.

T09 · Insecure Skill Coding Practices

Warning
Location
cron-job.js:139
Finding

Hard-Coded Telegram Recipient in Externally Consumed Message Payload

Content
View full analysis

Vulnerability Details

File Location: cron-job.js, lines 139-151
Vulnerability Type: Undeclared fixed-recipient external message routing
Risk Level: Medium

Vulnerable Code

js
const jsonOutput = {
  success: true,
  timestamp: new Date().toISOString(),
  timezone: 'Asia/Shanghai',
  chat_id: '8428610733',
  channel: 'telegram',
  message: message,
  items: items.slice(0, limit),
  format: 'markdown'
};

const jsonFile = path.join(__dirname, 'daily-hot-trend-output.json');
fs.writeFileSync(jsonFile, JSON.stringify(jsonOutput, null, 2), 'utf-8');

Technical Analysis

The scheduled-report wrapper embeds the fixed Telegram chat identifier 8428610733 in a message payload intended for consumption by OpenClaw tooling. The Skill documentation declares Douyin trend retrieval but does not identify this recipient or clearly declare fixed-recipient Telegram delivery as part of the required functionality.

cron-job.js does not directly contact Telegram or install a scheduled task. It writes the payload to daily-hot-trend-output.json and prints content for an external integration to capture. Exploitation or unintended delivery therefore depends on a downstream OpenClaw component treating this output as an instruction to send the message.

A fixed recipient violates recipient-control and least-privilege expectations because users cannot explicitly select or approve the destination. The behavior exceeds what is necessary to retrieve and format public trend data.

Attack Path

  1. A user or existing scheduler executes cron-job.js.
  2. The script retrieves and formats the Douyin trend report.
  3. It constructs a JSON object containing the hard-coded chat_id.
  4. The object is written to daily-hot-trend-output.json, while the script states that the message is prepared for Telegram.
  5. A configured OpenClaw or messaging integration reads or captures the payload.
  6. If that integration trusts the embedded rout ...[truncated 941 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the hard-coded Telegram chat identifier from source code.
  2. Require the destination to be supplied through explicit, trusted configuration or a user-approved invocation parameter.
  3. Validate the recipient identifier according to the messaging integration's expected format.
  4. Fail closed when no recipient has been configured instead of falling back to an embedded account.
  5. Keep retrieval and delivery separate: the trend-retrieval Skill should return structured data, while a distinct messaging component should select and authorize the recipient.
  6. Clearly document Telegram delivery, destination selection, data transmitted, and scheduling behavior in SKILL.md.
  7. Require user confirmation before first-time delivery to a new recipient.
  8. Avoid placing routing instructions in output that a downstream agent may automatically trust without policy checks.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the implementation omits advertised outputs such as links and cover images while performing undeclared local TXT/JSON persistence. Undisclosed file creation is a meaningful security concern in agent environments because it can leave residual data, overwrite artifacts, or create a covert storage channel inconsistent with a seemingly read-only fetch-and-print skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The finding indicates the implementation omits advertised outputs such as links and cover images while performing undeclared local TXT/JSON persistence. Undisclosed file creation is a meaningful security concern in agent environments because it can leave residual data, overwrite artifacts, or create a covert storage channel inconsistent with a seemingly read-only fetch-and-print skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The finding indicates the implementation omits advertised outputs such as links and cover images while performing undeclared local TXT/JSON persistence. Undisclosed file creation is a meaningful security concern in agent environments because it can leave residual data, overwrite artifacts, or create a covert storage channel inconsistent with a seemingly read-only fetch-and-print skill.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
node scripts/douyin.js hot

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

md
node scripts/douyin.js hot

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code formats content specifically for Telegram Markdown and prepares link-bearing messages despite the skill being described only as a data retrieval tool. This increases risk because fetched content is transformed into a broadcast-ready payload, which can facilitate unintended dissemination of untrusted external content through another channel.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code explicitly formats the timestamp using the zh-CN locale and Asia/Shanghai timezone, which imposes a specific language/locale setting in user-facing output. There is no opt-in, configuration, or indication that this is a region-specific tool requiring that locale.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script embeds a specific Telegram chat_id and prepares outbound delivery artifacts that extend beyond the stated skill purpose of retrieving Douyin hot-trend data. Hardcoding a recipient and packaging content for downstream messaging creates an unintended data-exfiltration or unauthorized broadcasting path if the job is enabled in an automation environment.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest says the skill outputs titles, heat values, jump links, and cover images where available, across multiple hot-content domains. This file only shows a Douyin hot list message with titles and heat values, provides links for only some entries, and contains no cover-image output at all, indicating the implemented/output behavior is narrower than the stated description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The output includes Telegram-specific delivery metadata (such as chat_id and channel) and a preformatted push message, which goes beyond the stated purpose of returning Douyin trending data. If this file is exposed to unintended consumers, it can leak integration details and facilitate misuse of messaging infrastructure or privacy-sensitive routing information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The message body is entirely in Chinese and appears to be the fixed user-facing output for the skill. For all file types, a locale policy violation should be flagged when a specific language is forced without user opt-in or clear justification, and no such choice or justification is present here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The package declares a required environment variable, SKILLBOSS_API_KEY, even though the stated functionality is only to fetch Douyin hot-trend data. Requiring a secret that is not clearly necessary expands the skill's access to sensitive credentials and creates unnecessary exposure if the implementation transmits, logs, or misuses that key.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script reads an API credential from the environment and automatically sends it to an external service without any runtime disclosure or consent flow. In an agent-skill context, this can expose user or platform secrets to a third-party endpoint unexpectedly, especially if users assume the skill only contacts Douyin directly.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/douyin-with-cover.js (reported line 9)May include surrounding context.

js
*/

const API_KEY = process.env.SKILLBOSS_API_KEY
const API_BASE = 'https://api.heybossai.com/v1'

async function pilot(body) {
  const r = await fetch(`${API_BASE}/pilot`, {

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The script transmits data to an external third-party service (api.heybossai.com) using a bearer API key and relies on that service to fetch and return content. This expands the trust boundary: request contents, target URLs, and returned data are exposed to the external provider, and the script performs no validation of the remote response before parsing and displaying it. In the context of a data-fetching skill this is somewhat expected, but it still creates a real data exposure and supply-chain risk if the service is compromised, misconfigured, or not approved for the environment.

Content

Scanner excerpt · scripts/douyin.js (reported line 9)May include surrounding context.

js
*/

const API_KEY = process.env.SKILLBOSS_API_KEY
const API_BASE = 'https://api.heybossai.com/v1'

async function pilot(body) {
  const r = await fetch(`${API_BASE}/pilot`, {

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a data-retrieval skill that returns hot-list content. While network access to fetch Douyin data is expected, invoking a separate process via child_process adds a code-execution capability beyond that purpose and is not clearly necessary from the skill description alone.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest says the skill obtains Douyin hot-list data and outputs fields such as titles, heat values, links, and cover images. This script additionally persists the formatted report and raw data to latest-hot-trend.txt and latest-hot-trend.json, introducing local stateful file output that is not described in the skill's stated behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This JSON file contains only Chinese-language output and China-specific platform content, while also specifying the timezone as Asia/Shanghai. For SQP-3, a language/locale policy issue exists when a skill appears to force a specific language or locale without offering user opt-in or documenting why that locale is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire skill description is presented only in Chinese, with no indication that users may choose another language or that the locale is intentionally constrained. Under the policy rule for language/locale, this is a natural-language policy concern because the skill effectively imposes a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module comment states '直接发送到 Telegram', implying actual message transmission. However, the implementation only formats a Telegram message, writes text/JSON files, and logs that the message is ready; there is no network call or Telegram API invocation that performs sending.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This plain-text skill content presents all user-facing information exclusively in Chinese, including the title, schedule, topic labels, and data-source note. Under the policy criteria, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest says the skill outputs title, popularity value, link, and cover image when available. The structured items here contain rank, title, popularity, link, and label fields, but no cover-image field appears anywhere in the output, creating a mismatch with the advertised output contract.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Multiple user-visible strings, including status messages and usage help, are only provided in Chinese. This can violate language/locale policy when no user choice or documented locale restriction is offered.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The stated purpose is to obtain Douyin hot-ranking data and output titles, heat values, links, and cover images. While network access is expected for that purpose, this implementation also depends on a separate SkillBoss API credential and routes the request through a generic external '/pilot' scraper service, which is a broader capability not justified by the manifest description itself.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
cron-job.js:16

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/get-hot-trend.js:16