Back to skill

Security audit

review-manager

Security checks for vulnerabilities and agentic risk

Overview

This skill is a plausible review-management tool, but its Discord alert/report scripts can execute shell commands from untrusted review text and it under-discloses customer-data sharing risks.

Review this carefully before installing. Do not enable Discord alerts or scheduled heartbeat/cron runs until the command execution paths are changed to argument-array APIs, review JSON is validated, and the skill clearly documents what customer data is stored locally or sent to Discord.

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/check-negative.js:68
Finding

Shell Command Injection Through Negative Review Alerts

Content
View full analysis
`**[${review.platform}]** ${review.author} ⭐${review.rating}\n` + `사유: ${reason}\n` + `> ${review.content}\n` ).join('\n'); sendDiscordAlert(config.alert.discordChannelId, message); ``` ### Technical Analysis The script creates a command as a single string and executes it through `execSync()`, which invokes a system shell. It attempts to secure the message by escaping only double-quote characters: ```js message.replace(/"/g, '\\"') ``` Escaping double quotes does not neutralize shell substitutions inside a double-quoted shell argument. Constructs such as `$(command)` and backtick command substitution are still interpreted by the shell. Review content, author names, platform values, and the configured Discord channel ID are interpolated into this shell command. The script loads every JSON file under the configured review directory without validating the structure or sanitizing individual fields. Therefore, malicious content in a persisted review can reach the command execution sink. ### Attack Path 1. Discord alerts are enabled in `config.json`, and the negative-review checker is invoked manually or through the documented recurring automation. 2. A malicious r ...[truncated 1880 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/weekly-report.js:167
Finding

Shell Command Injection Through Review-Derived Weekly Report Keywords

Content
View full analysis
`- ${word} (${count}회)`).join('\n')} `; ``` Review content is tokenized without shell-oriented validation: ```js const tokens = review.content.split(/\s+|[.,!?]/); for (const token of tokens) { const word = token.trim(); if (word.length >= 2 && !stopwords.has(word)) { words[word] = (words[word] || 0) + 1; } } ``` ### Technical Analysis The weekly report command is assembled as one shell string and passed to `execSync()`. Although double quotes in the message are escaped, shell substitutions remain active within a double-quoted argument. Keywords are derived from review content by splitting on whitespace and limited punctuation. Shell metacharacters such as `$`, parentheses, and backticks are not removed. A malicious token containing command-substitution syntax can therefore become a top report keyword and be inserted into the command string. The vulnerable path is reached when the user runs: ```bash node scripts/weekly-report.js --send discord ``` The configured Discord channel ID is also interpolated without validation. ### Attack Path 1. A malicious review object is placed in a JSON file under the configured review directory. 2. Its date is within the last seven days, causing `filterLastWeek()` to include it. 3. The review content contains a token using shell substitution syntax. 4. `extractKeywords()` pr ...[truncated 1475 chars]
Remediation
View remediation
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 (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

설명은 리뷰 수집·자동답글·알림·리포트·감성분석·경쟁사 비교를 포함한 통합 리뷰 관리 스킬을 주장하지만, 제공된 코드 조각은 그중 일부인 '미답변 리뷰에 대한 답글 문구 생성 및 로컬 저장'만 수행한다. 리뷰는 외부 플랫폼에서 수집하지 않고 로컬 reviews 디렉터리의 JSON 파일에서만 읽는다. 답글도 실제 네이버/구글/배민/쿠팡 등에 등록하지 않으며, 해당 부분은 TODO로 남아 있다. 또한 감성분석은 모델 이름만 인자로 넘길 뿐 실제 분석은 하지 않고, 알림/리포트/경쟁사 비교 로직도 전혀 없다. 따라서 선언된 설명이 코드의 실제 기능 범위를 상당히 과장하고 있어 불일치로 판단된다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

설명은 리뷰 수집뿐 아니라 자동답글, 알림, 리포트, 감성분석, 경쟁사 비교를 포함한 통합 관리 솔루션을 주장한다. 그러나 제공된 코드 조각은 오직 리뷰 수집용 스크립트이며, 그마저도 실제 API 호출이나 브라우저 자동화가 아니라 mock 데이터 반환과 로컬 파일 저장이 중심이다. 네이버/구글/배민/쿠팡 플랫폼명을 다루는 점은 설명과 일부 일치하지만, 핵심 부가 기능들이 전혀 구현되지 않았고 실제 수집도 부분적으로 미구현이므로 선언된 설명을 정확히 대표한다고 보기 어렵다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

설명은 종합 리뷰 관리 플랫폼처럼 여러 외부 플랫폼의 리뷰 모니터링, 자동답글, 알림, 감성분석, 경쟁사 비교까지 제공한다고 주장합니다. 그러나 제공된 코드 조각은 오직 경쟁사 비교 리포트 스크립트 하나로, 로컬 리뷰 파일을 읽어 자사 평균 평점/최근 리뷰 수를 계산하고, 경쟁사 데이터는 TODO와 함께 mock 난수로 생성합니다. 즉 '경쟁사 비교'라는 일부 주제와는 관련이 있지만, 실제 외부 플랫폼 리뷰 수집이나 통합 모니터링은 수행하지 않고, 자동답글·알림·감성분석도 전혀 구현되어 있지 않습니다. 따라서 선언된 설명은 이 코드 조각의 실제 동작을 과장하고 있으며, 설명과 코드 사이에 실질적 불일치가 있습니다.

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 122)May include surrounding context.

md
0 * * * * cd ~/.openclaw/workspace/skills/review-manager && node scripts/check-negative.js

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to send weekly reports to Discord, an external third-party service, without warning that business metrics and review-derived data will leave the local environment. This can expose customer content or commercially sensitive information to an external platform, especially if reports include raw reviews, sentiment analysis, or competitor comparisons.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly documents storing collected reviews, generated replies, reports, and alert history in local files, but provides no warning about privacy, retention, access control, or handling of potentially sensitive personal/business data. Because review content can contain names, contact details, health information, or defamatory content, unguarded local persistence increases the risk of unauthorized disclosure and accidental long-term retention.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
79% confidence
Finding

The skill advertises and instructs execution of Node.js scripts that process local configuration and likely access environment-provided secrets or runtime context, but it declares no explicit tool scope or permissions boundary. This weakens least-privilege guarantees and can cause users or orchestration systems to run a data-collecting skill without understanding what capabilities it may use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill encourages sending collected reviews and weekly reports to Discord without warning that review content may include personal data, sensitive complaints, order details, or employee names. Forwarding that data to a third-party messaging platform can create privacy, compliance, and unauthorized disclosure risks, especially in a business context handling customer feedback across multiple services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reply templates are fixed in Korean and there is no indication that the user can choose a language or that the skill is intentionally limited to a Korean-language context. This can violate language/locale policy when a skill forces a specific language without opt-in or justification.

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 says this script is for 'AI 기반 리뷰 자동 답글 생성', which implies actual AI/LLM-driven reply generation. However, generateReply only selects canned text based on rating, and the inline comments at L59-L60 explicitly acknowledge that real Claude/API integration is not implemented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt string explicitly requires replies in '자연스러운 한국어', making the skill produce Korean-language output regardless of user preference or review locale. This is a natural-language locale policy issue because the file does not offer a language choice or explain a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script builds a shell command with interpolated channelId and message data and executes it via execSync. Although double quotes are escaped in the message, shell metacharacters such as command substitution are not safely handled, and channelId is inserted without sanitization, creating command-injection risk if configuration or review content is attacker-controlled. In this skill context, review text is external/untrusted input, which makes the subprocess boundary significantly more dangerous.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The alert payload sends reviewer author names and full review content to Discord, which can expose personal or sensitive customer data to a third-party channel without minimization or explicit disclosure/consent controls. Because this skill aggregates customer reviews across platforms, the data handling context increases privacy risk, especially if the Discord workspace includes broader staff access or external parties.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file description and all user-facing console messages are written in Korean, indicating the skill is intended to operate in a single language with no opt-in or fallback. This can violate language/locale policy when users are not explicitly given a choice or informed of the constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script builds a shell command with untrusted data from config.alert.discordChannelId and review-derived message content, then executes it via execSync. Escaping only double quotes is insufficient for shell safety, so shell metacharacters or command substitutions embedded in the channel ID or message can lead to command injection; additionally, review content is transmitted to Discord, creating an external data exposure path for potentially sensitive customer data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The natural-language instructions and headings are presented only in Korean, which effectively forces a specific language for skill use and setup. Under the policy, locale or language constraints should either be optional for the user or explicitly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The description and operational guidance are entirely Korean-focused, and the skill's automated reply capability is presented as generating responses in that locale without any mention of user-selectable language or regional scope. This can violate language/locale policy when a skill implicitly enforces a specific language absent opt-in or justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This manifest-style JSON defines operational settings for the skill but provides no explicit trigger phrases, activation conditions, or exclusion criteria. For manifest files, missing specificity about when the skill should activate can lead to ambiguous or overly broad invocation behavior if other components infer activation from this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file's natural-language description and user-facing messages are written in Korean, which effectively fixes the skill's interaction language. There is no indication that the locale is optional, user-selected, or justified as a region-specific tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Multiple comments and user-visible messages are written only in Korean, including status output and report text. This enforces a specific language/locale without any visible opt-in, fallback, or documented region-specific justification in the file.

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
scripts/check-negative.js:80

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/weekly-report.js:171