Back to skill

Security audit

xhs-convert-url-pro

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it handles account tokens and paid quota over insecure default transport, which users should review before installing.

Install only if you trust this provider with Xiaohongshu links, phone/account profile data, task results, and paid quota. Use an HTTPS base URL, avoid insecure=true, protect ~/.xhs-platform/config.json, and confirm before registration, login, or paid task submission.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
src/config.js:14
Finding

Bearer Tokens and Account Data Transmitted over Plaintext HTTP by Default

Content
View full analysis

Vulnerability Details

File Location: src/config.js:14; data flow to src/client.js:48-71
Vulnerability Type: Plaintext transmission of credentials and sensitive data
Risk Level: High

Relevant code:

js
// src/config.js:14
const DEFAULT_BASE_URL = 'http://st.aidata366.com';
js
// src/client.js:48-71
async request(method, apiPath, opts = {}) {
  const { body, headers = {} } = opts;
  // Plain HTTP with a token only produces a warning; the request continues.
  if (!_httpWarned && this.token && this.baseUrl.startsWith('http://')) {
    _httpWarned = true;
    process.stderr.write('[warn] Current service address uses plaintext HTTP; token will be transmitted in plaintext\n');
  }
  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), REQUEST_TIMEOUT_MS);
  let res;
  let payload = null;
  try {
    res = await fetch(this.baseUrl + '/api/v1' + apiPath, {
      method,
      headers: {
        ...(body ? { 'Content-Type': 'application/json' } : {}),
        ...(this.token ? { Authorization: `Bearer ${this.token}` } : {}),
        ...headers,
      },
      body: body ? JSON.stringify(body) : undefined,
      signal: ctrl.signal,
    });

The displayed English warning text above is a translation for report readability; the source warning at src/client.js:54 is written in Chinese and explicitly states that the token is transmitted in plaintext.

Technical Analysis

The built-in production endpoint uses HTTP rather than HTTPS. resolveConfig() selects this endpoint whenever the user has not supplied a command-line override, environment override, or saved endpoint. ApiClient.request() then sends API traffic to that endpoint.

Authenticated requests place the bearer token in the Authorization header. The same client also performs the unauthenticated session-check exchange that returns the long-lived bearer token in its HTTP ...[truncated 2736 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the production default with an authenticated HTTPS endpoint and configure valid certificates:

    js
    const DEFAULT_BASE_URL = 'https://st.aidata366.com';
    
  2. Reject plaintext HTTP for all non-loopback destinations, especially for authentication and authenticated API calls. A warning is insufficient:

    js
    const parsed = new URL(this.baseUrl);
    const loopback = ['localhost', '127.0.0.1', '::1'].includes(parsed.hostname);
    if (parsed.protocol !== 'https:' && !loopback) {
      throw new NetworkError('HTTPS is required for non-loopback service endpoints');
    }
    
  3. Apply the transport check before creating sessions or checking session status, not only when a bearer token is already present. This protects credentials returned in responses as well as credentials sent in requests.

  4. Remove the process-wide NODE_TLS_REJECT_UNAUTHORIZED=0 mechanism from production workflows. If development support for private certificates is required, use a narrowly scoped custom certificate authority or per-client TLS configuration and restrict it to explicitly selected development endpoints.

  5. Update SKILL.md, API.md, and openapi.yaml to advertise only the HTTPS production endpoint. Keep HTTP examples limited to explicit loopback development services.

  6. After deployment of HTTPS enforcement, revoke bearer tokens that may previously have traversed plaintext connections and require affected users to authenticate again.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation explicitly permits HTTP and shows a Base URL using plain HTTP while requiring Bearer tokens for authenticated requests. This exposes session tokens, phone numbers, quota data, and task results to interception or manipulation by any attacker on the network path, enabling account takeover and unauthorized API use.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · API.md (reported line 318)May include surrounding context.

提交是异步的,需继续用 6.2 轮询直到终态。

bash
curl -s -X POST http://st.aidata366.com/api/v1/tasks \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: $(printf '%s\n' "URL1" "URL2" | sha256sum | cut -c1-32)" \

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

文件中自然语言明确规定失败响应 message 为“中文可读错误描述”,且未说明可根据用户偏好返回其他语言,也未提供语言选择或 opt-in 机制。根据规则,强制特定语言而不给用户选择属于自然语言层面的语言/locale policy violation。

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The example instructs callers to POST an access_token to an HTTP endpoint, normalizing plaintext credential transmission in client implementations. Even though this specific token is a temporary session token, interception lets an attacker poll or complete the login flow and obtain the long-lived Bearer token, leading to account compromise.

Content

Scanner excerpt · API.md (reported line 168)May include surrounding context.

调用方处理建议:以 3~5 秒间隔轮询本接口,直到 status 变为 ready 或超过 expires_in;超时需重新走 4.1 建会话。客户端侧 pending 与「会话已过期/已使用」应分别映射为 LOGIN_PENDING / LOGIN_EXPIRED 两种提示。

bash
curl -s -X POST http://st.aidata366.com/api/v1/auth/cli-session/check \
  -H "Content-Type: application/json" \
  -d '{"access_token":"f83e0c4bfa7918318843646568ecd43f"}'

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to use shell, network, and environment-backed capabilities, but it does not declare any explicit tool scope or allowed-tools constraints. This creates an over-privileged execution pattern where an agent may invoke broader local commands, read sensitive configuration like tokens from ~/.xhs-platform/config.json, or contact arbitrary endpoints such as a user-configurable base-url without policy-level restriction.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger description includes broad keywords like '小红书', '转链', '链接转换', and 'xhslink', which can overlap with normal conversation and cause the skill to activate unexpectedly. Mis-triggering is risky here because the skill can initiate login flows, handle tokens, invoke paid actions, and send user data to an external service, so accidental activation can lead to privacy exposure or unwanted charges.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

L065 说明“agent 必须把注册引导原样发给用户”,而该固定话术为中文;L096 也对登录引导作出相同要求。文件中未说明可根据用户语言偏好切换或提供其他语言版本,因此对非中文用户构成强制语言约束。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code's natural-language interface, including the top-level description, usage text, and operational prompts, is entirely in Chinese. The file does not provide an opt-in language selection, alternate locale, or documentation that the tool is intentionally limited to a Chinese-only regional context, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
98% confidence
Finding

The code explicitly disables TLS certificate verification process-wide by setting NODE_TLS_REJECT_UNAUTHORIZED='0'. This allows man-in-the-middle interception of API traffic, including bearer tokens and task data, and the risk is amplified because this skill handles authenticated requests and may already permit plaintext HTTP in some deployments.

Content

Scanner excerpt · src/client.js (reported line 16)May include surrounding context.

js
/** 忽略 HTTPS 证书校验 (服务端自签/域名不匹配证书时由 insecure 配置开启)。进程级, 仅提示一次。 */
function allowInsecureTls() {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  if (!_insecureNoted) {
    _insecureNoted = true;
    process.stderr.write('[warn] 已按配置忽略 HTTPS 证书校验(insecure=true)\n');

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes this skill as a 小红书链接批量转链工具, but the module documentation states it shares a persistent credential/config file and token with a separate xhs-dpt data-collection skill. Persisting and reusing cross-skill authentication state is a broader platform/account-management behavior than simple URL conversion, and that broader behavior is not disclosed in the manifest description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file loads, merges, and saves a user-level config containing a token, and also reads environment variables to resolve effective credentials and transport settings. For a skill described narrowly as converting 小红书 links, long-lived credential storage and cross-session account configuration are not clearly justified by the stated purpose alone.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The comment on L65 states that timeout handling throws a BizError('TIMEOUT'), and the implementation on L74 constructs new BizError(...). However, this file does not define or import BizError, so the actual runtime behavior would be a ReferenceError rather than the documented business error flow. This is an intent-code divergence because the inline documentation describes a specific error contract that the code as written cannot fulfill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

Natural-language policy checks apply to all file types. The title and descriptive text are entirely in Chinese, and the document does not state that the skill is China-specific or that users may choose another language, which can violate a language/locale policy requiring opt-in or documented justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This is a manifest-style file, so vague-trigger checks apply. The description broadly states that the service converts Xiaohongshu note links in bulk, but it does not define any explicit trigger phrases, activation boundaries, or exclusion examples, which could lead to overly broad invocation by an agent integrating from this manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The package description is entirely in Chinese and presents the skill as Chinese-language specific without any indication that users can choose another language or locale. Under the policy rule for natural-language constraints, this can be treated as a locale/language restriction that is not explicitly opt-in or justified in the manifest text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language documentation in the file is written entirely in Chinese, which imposes a specific language/locale on maintainers and users of the skill without any opt-in or explanation that the skill is region-specific. This matches the policy category for language or locale constraints that are not optional or justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file-level comment specifies output conventions and operational guidance entirely in Chinese, and later user-facing error/help messages are also fixed in Chinese. Under the language/locale policy rule, forcing a specific language without opt-in can be a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.insecure_tls_verification

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
src/client.js:16