Back to skill

Security audit

获取微博热搜榜数据,返回热搜标题、热度值和跳转链接。当用户需要查看微博热搜、微博热点、微博热榜时使用此技能。支持自定义获取条数(默认50条)。

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently fetches and displays public Weibo hot-search data, with minor hardening issues but no hidden persistence, credential access, or unrelated behavior.

Install only if you are comfortable with the skill making a direct HTTPS request to Weibo and printing remote hot-search text in your terminal. For safer operation, the publisher should add response-size limits, HTTP status/content-type checks, terminal-output sanitization, and stricter validation of the optional result count.

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

Warning
Location
scripts/weibo.js:26
Finding

Unbounded HTTP Response Buffering Enables Memory Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/weibo.js, lines 26-34
Vulnerability Type: Unbounded response buffering
Risk Level: Medium

js
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
  try {
    const json = JSON.parse(data);
    resolve(json);
  } catch (e) {
    reject(new Error('Response parsing failed: ' + e.message));
  }
});

Technical Analysis

The script appends every received response chunk to an in-memory string without enforcing a maximum response size. The configured request timeout limits how long the request may remain active, but it does not limit how many bytes can be received during that period.

The implementation also attempts to parse the entire accumulated response as JSON. Consequently, both response buffering and JSON parsing can require substantial memory. No validation of the Content-Length header, HTTP status code, or response content type occurs before buffering.

Attack Path

  1. The script requests data from the configured Weibo endpoint.
  2. The endpoint, or an attacker capable of influencing its response, returns an abnormally large or continuously streamed body within the timeout window.
  3. Each response chunk is appended to the data string without a byte limit.
  4. The Node.js process consumes increasing amounts of memory.
  5. If transmission completes, the process attempts to parse the entire body, causing additional CPU and memory pressure.
  6. The process may become unresponsive or terminate because of memory exhaustion.

Exploitation requires control over, or the ability to influence, the HTTPS response. TLS substantially limits ordinary network interception, but it does not protect against a compromised upstream service, trusted certificate authority compromise, or unexpected upstream behavior.

Impact Assessment

The primary impact is denial of service against the local Node.js process. Depending on av ...[truncated 328 chars]

Remediation
View remediation

Remediation Suggestions

  • Enforce a strict response-size limit while streaming, such as one or two megabytes.
  • Track bytes using Buffer.byteLength() rather than relying on JavaScript string length.
  • Destroy the request and reject the operation immediately when the limit is exceeded.
  • Validate that the HTTP status code indicates success before reading the body.
  • Validate the response content type before attempting JSON parsing.
  • Reject a declared Content-Length that exceeds the configured limit, while still enforcing the streaming limit because that header may be missing or inaccurate.
  • Consider parsing and validating the response in an isolated process if availability requirements are strict.

Example hardening pattern:

js
const MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
let receivedBytes = 0;
const chunks = [];

if (res.statusCode !== 200) {
  req.destroy();
  return reject(new Error(`Unexpected HTTP status: ${res.statusCode}`));
}

res.on('data', chunk => {
  receivedBytes += chunk.length;
  if (receivedBytes > MAX_RESPONSE_BYTES) {
    req.destroy();
    reject(new Error('Response exceeds the permitted size'));
    return;
  }
  chunks.push(chunk);
});

res.on('end', () => {
  try {
    resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')));
  } catch (error) {
    reject(new Error(`Response parsing failed: ${error.message}`));
  }
});

T09 · Insecure Skill Coding Practices

Note
Location
scripts/weibo.js:61
Finding

Remote API Values Are Printed Without Terminal-Control Sanitization

Content
View full analysis

Vulnerability Details

File Location: scripts/weibo.js, lines 61-69
Vulnerability Type: Terminal escape-sequence injection
Risk Level: Low

js
const title = item.word || item.note || 'Unknown';
const hot = item.num ? `${Math.round(item.num / 10000)} units` : (item.raw_hot || '');
const label = item.label_name ? ` [${item.label_name}]` : '';
const url = `https://s.weibo.com/weibo?q=%23${encodeURIComponent(title)}%23`;

console.log(`${rank}. ${title}${label}`);
if (hot) console.log(`    Popularity: ${hot}`);
console.log(`    Link: ${url}`);
console.log();

The displayed English literals above correspond to the original localized literals; the vulnerable data flow and operations are unchanged.

Technical Analysis

The values assigned from item.word, item.note, item.label_name, and potentially item.raw_hot originate in the remote API response. These values are interpolated directly into strings passed to console.log().

Encoding the title with encodeURIComponent() protects the generated URL component, but it does not sanitize the separately printed title or label. If a remote value contains ANSI escape sequences or other C0/C1 control characters, the terminal may interpret them as commands rather than display them as ordinary text.

Possible effects depend on the terminal implementation and configuration. They can include clearing or rewriting visible output, changing colors to conceal content, forging status messages, setting a misleading terminal title, or creating deceptive terminal hyperlinks. No direct shell invocation is present in this code.

Attack Path

  1. An attacker gains the ability to influence a hot-search record returned by the upstream API, or the upstream service becomes compromised.
  2. The attacker places terminal control characters in a title, note, label, or raw popularity value.
  3. The script parses the value as valid JSON without rejecting control sequences r ...[truncated 976 chars]
Remediation
View remediation

Remediation Suggestions

  • Sanitize every string obtained from the remote response before writing it to a terminal.
  • Remove ANSI escape sequences and nonessential C0/C1 control characters.
  • Preserve only explicitly permitted formatting characters, such as ordinary spaces, or replace line breaks and tabs with safe visible equivalents.
  • Apply length limits to titles, labels, and popularity values to prevent output flooding.
  • Continue using encodeURIComponent() for URL query values, but do not treat URL encoding as terminal sanitization.
  • Validate the expected JSON schema and reject values that are not of the expected primitive type.

Example hardening pattern:

js
function sanitizeTerminalText(value, maxLength = 200) {
  return String(value ?? '')
    .replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '')
    .replace(/[\x00-\x08\x0B-\x1F\x7F-\x9F]/g, '')
    .replace(/[\r\n\t]/g, ' ')
    .slice(0, maxLength);
}

const title = sanitizeTerminalText(item.word || item.note || 'Unknown');
const labelName = sanitizeTerminalText(item.label_name, 40);
const rawHot = sanitizeTerminalText(item.raw_hot, 40);
const label = labelName ? ` [${labelName}]` : '';
const hot = item.num ? `${Math.round(item.num / 10000)} units` : rawHot;
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/weibo.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/weibo.js

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The request headers force Accept-Language to zh-CN,zh;q=0.9, which imposes a specific language/locale preference in the skill behavior. The file does not provide an opt-in, override, or justification that this locale restriction is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script formats timestamps using toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }), which hard-codes both language and locale-specific regional settings. No user choice or documented justification is provided in the file.

Content

No source excerpt is available for this finding.