Back to skill

Security audit

Skill Rating Comparator

Security checks for vulnerabilities and agentic risk

Overview

This skill does not appear to steal data or persist on the system, but it presents mock and random ratings as if they came from real Skill and repository analysis.

Review this skill carefully before installing if you expect factual comparison results. It appears safe from a host-access perspective in the inspected source, but its reports should be treated as demo or placeholder output unless the publisher implements real ClawHub/GitHub lookup, deterministic scoring, provenance, and Markdown escaping.

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

Note
Location
src/index.ts:481
Finding

Unescaped User-Controlled Skill Name Enables Markdown Content Injection

Content
View full analysis

Vulnerability Details

File Location: src/index.ts:481-489, src/index.ts:250-252, and src/index.ts:424-437
Vulnerability Type: Markdown content injection caused by insufficient input validation and output encoding
Risk Level: Low

Vulnerable Code

typescript
const patterns = [
  /^(?:对比 | 评分 | 分析 | 评测)\s*(.+?)(?:\s*--.*)?$/i,
  /^(?:skill 评分|skill 对比 |skill 分析)\s*(.+?)$/i,
  /^(?:帮我 | 请)\s*(?:对比 | 评分 | 分析 | 评测)\s*(.+?)$/i,
];

let skillName = '';
for (const pattern of patterns) {
  const match = content.match(pattern);
  if (match) {
    skillName = match[1].trim();
    break;
  }
}

The captured value is stored without validation:

typescript
const targetRating: SkillRating = {
  skillId: targetSkill,
  name: targetSkill,
  platform: 'clawhub',

It is then interpolated directly into Markdown:

typescript
let md = `## 📊 Skill 评分对比报告\n\n`;
md += `**目标 Skill:** ${targetSkill.name}\n`;
md += `**对比对象:** ${competitors.length} 个同类 Skill\n\n`;

md += `### 综合评分\n\n`;
md += `| 排名 | Skill | 平台 | 综合得分 | 功能 | 代码 | 文档 | 评价 | 更新 | 安装 |\n`;
md += `|------|-------|------|---------|------|------|------|------|------|------|\n`;

allSkills.forEach(skill => {
  const rankEmoji = skill.rank === 1 ? '🥇' : skill.rank === 2 ? '🥈' : skill.rank === 3 ? '🥉' : '';
  md += `| ${rankEmoji} ${skill.rank} | ${skill.name} | ${skill.platform} | **${skill.totalScore}** | `;
  md += `${skill.scores.functionality} | ${skill.scores.codeQuality} | ${skill.scores.documentation} | `;
  md += `${skill.scores.userReviews} | ${skill.scores.updateFrequency} | ${skill.scores.installation} |\n`;
});

Technical Analysis

The command parser permits arbitrary characters in the captured Skill name through (.+?). The resulting value is copied into targetRating.name and inserted into both ordinary Markdown and a Markdown table without contextual encoding.

An attacker can supply Markdown metacharacters such as pipes, line breaks, headings, links, or image ...[truncated 1482 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate the requested Skill identifier before using it. If Skill names follow a registry format, enforce a strict allowlist and length limit:
typescript
const SKILL_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$/;

if (!SKILL_NAME_PATTERN.test(skillName)) {
  return {
    type: 'text',
    content: 'Invalid Skill identifier.',
  };
}
  1. Apply context-specific Markdown escaping even after validation. Escape at least backslashes, pipes, brackets, parentheses, backticks, asterisks, underscores, angle brackets, and line breaks as appropriate for the output context.

  2. Use a separate table-cell encoder because pipes and newline characters can alter Markdown table structure:

typescript
function escapeMarkdownTableCell(value: string): string {
  return value
    .replace(/\\/g, '\\\\')
    .replace(/\|/g, '\\|')
    .replace(/\r?\n/g, ' ')
    .replace(/([`*_[\]<>])/g, '\\$1');
}
  1. Prefer structured UI components or plain-text responses when displaying untrusted values if the SDK supports them.

  2. Add security tests covering malicious names containing table delimiters, line breaks, links, image syntax, headings, HTML-like text, backticks, and excessively long input.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README presents the skill name, description, and all usage examples exclusively in Chinese, including the invocation phrases users are told to send. This suggests a language-specific interaction model without offering an alternative language or documenting that the skill is intentionally limited to Chinese users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Nearly all user-facing instructions, examples, and descriptions are presented only in Chinese, which effectively forces a specific language for interaction and understanding. The file does not offer an opt-in language choice or explain that the skill is intentionally limited to a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly states that it searches ClawHub and GitHub, but the documentation does not clearly warn that using it causes outbound network access to third-party services. Users may unknowingly expose prompts, repository identifiers, or usage patterns to external platforms, making the omission a meaningful transparency and consent issue.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrases are broad natural-language requests such as comparing or analyzing a skill, which could cause the agent to invoke this skill for ordinary conversation that did not explicitly request external comparison behavior. Because the skill is designed to search external platforms and generate evaluative reports, accidental activation can lead to unintended network access, data retrieval, or misleading autonomous judgments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description uses Chinese-only wording for the skill's behavior, indicating the skill is presented in a specific language without documenting any user choice or opt-in. Under the policy, forcing a specific language or locale without user selection is a natural-language policy violation unless clearly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The header comment promises automatic discovery and multidimensional analysis of similar skills, but the implementation relies on hardcoded competitor data and simulated scoring. In a decision-support skill, this is dangerous because it can mislead users into trusting fabricated comparisons and recommendations as if they were evidence-based results.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill’s natural-language description, labels, prompts, and usage examples are all written in Chinese, and the command parser later only recognizes Chinese trigger phrases. There is no visible indication that users may interact in another language or opt into a locale, which can violate a language/locale choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The regex patterns only accept Chinese commands such as “对比”, “评分”, “分析”, “评测”, “帮我”, and “请”, with only partial English support around the word “skill”. This effectively enforces a Chinese locale for invocation while not presenting users with a language choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This TypeScript test file uses Chinese for the title, comments, and all user-facing console output, with no indication that the skill is region-specific or that users can opt into another language. That creates a natural-language locale policy concern because the skill appears to enforce a specific language unconditionally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest description is written entirely in Chinese and presents the skill in that language without any indication that language is configurable or intentionally region-specific. Under the policy rule, forcing a specific language without opt-in can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
"author": "OpenClaw Skill Master",
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^25.5.0",
    "typescript": "^5.9.3"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"license": "MIT",
  "devDependencies": {
    "@types/node": "^25.5.0",
    "typescript": "^5.9.3"
  },
  "engines": {
    "node": ">=18.0.0"

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The inline comments describe substantive code and document analysis checks, but the function only returns a randomized placeholder score. This creates a false sense of rigor and can cause operators to make choices based on nonexistent analysis rather than validated measurements.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code-quality and documentation-analysis routines are presented as evaluating real quality signals, but in practice they only return random values near a fixed base score. This is risky because users may interpret the reported scores as meaningful assessments of repository quality when they are not grounded in any actual inspection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This TypeScript declaration file uses Chinese-language comments throughout, including interface descriptions and field annotations. The file does not indicate that the skill is region-specific or offer any language choice, which can conflict with organizational language/locale policy requirements for user-facing or maintainer-facing instructions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.