Back to skill

Security audit

Amazon Review Intelligence

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Amazon review-analysis tool, but it needs review because it can spend ARI credits automatically under server-side auto-confirm rules despite inconsistent billing-safety documentation.

Install only if you are comfortable giving this skill access to your ARI account and with its auto-confirm billing model. If installed, set autoconfirm off or a low explicit limit, use '只报价,不要执行' when you only want a quote, and review scheduled monitoring or competitor settings because they can affect future collection costs.

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

Warning
Location
scripts/ari.py:1145
Finding
Remote Quote Response Can Trigger Paid Analysis Without Explicit Per-Operation Confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ari.py:1145-1151` and `scripts/ari.py:1353-1363` **Vulnerability Type**: Billing-consent bypass caused by remote-controlled auto-confirmation **Risk Level**: Medium ### Vulnerable Code In the general analysis workflow: ```python # First-use confirmation exemption (server policy skill.autoConfirm): # automatically generate the report for initial low-cost operations. auto_confirmed = False if not confirm and q_data.get("autoConfirm") and q_data.get("sufficient"): confirm = True auto_confirmed = True if not confirm: return {"success": True, "data": {"confirmationRequired": True, "quote": q_data, "webUrl": q_data.get("webUrl"), "message": "User confirmation is required before adding --confirm."}, "links": links()} ``` In the VOC workflow: ```python # First-use confirmation exemption: execute directly when the server enables # auto-confirmation and collection plus reporting is within the returned limit. auto_max = int(analysis_quote.get("autoConfirmMaxCredits") or 0) auto_confirmed = (not args.confirm and bool(analysis_quote.get("autoConfirm")) and sufficient and total_credits <= auto_max) if not args.confirm and not auto_confirmed: combined_quote["autoConfirmRemaining"] = analysis_quote.get("autoConfirmRemaining") emit({"success": True, "data": combined_quote, "links": links()}, args.compact) return ``` This behavior conflicts with the billing-safety statement at `README.md:83-86`: ```text Paid commands (collect, analyze, and paid deepdive) must explicitly include --confirm before they execute. Without --confirm, they only return a quote. Credits must not be deducted until the user has been informed and has confirmed. ``` ### Technical Analysis The local `--confirm` flag is intended to establish a clear trust boundary between a quote-only request and a credit-c ...[truncated 2672 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Require local confirmation by default** - Never convert `confirm` to `True` based only on a quote response. - When `--confirm` is absent, return the quote and stop before any credit-consuming request. 2. **Make auto-confirmation an explicit local opt-in** - If persistent auto-confirmation is required, add a separate local configuration option that the user must deliberately enable. - Store the preference in the protected user configuration directory rather than deriving authorization solely from remote response fields. - Keep auto-confirmation disabled by default. 3. **Enforce a local charge ceiling** - Record a user-selected maximum credit amount locally. - Compare the server quote against that local ceiling. - Reject missing, malformed, negative, non-integer, or unexpectedly large pricing fields. - Require explicit `--confirm` whenever collection and analysis are combined or the total cannot be calculated reliably. 4. **Bind confirmation to the quoted operation** - Use a server-issued, short-lived quote identifier that binds the price, operation type, ASIN, site, and account. - Require the confirmed execution request to reference that exact quote. - Reject changed parameters and expired quotes. 5. **Separate quote and execution APIs** - Ensure quote endpoints cannot initiate paid work. - Ensure execution endpoints require an explicit confirmation signal or signed quote token. - Apply idempotency keys to prevent duplicate charges after timeouts or retries. 6. **Resolve documentation inconsistencies** - Update `README.md`, `SKILL.md`, and command help so they state one consistent consent policy. - If quote-only behavior is promised for invocations without `--confirm`, enforce that behavior unconditionally in code. - Clearly disclose any persistent auto-confirm setting, its limit, and how users can disable it. 7. **Add regression tests** - Verify that every paid ...[truncated 281 chars]
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (66)

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The README states '用中文直接描述需求即可', which directs use of Chinese as the interaction language. Because the document does not offer an explicit language choice or opt-in, this can be interpreted as a locale/language policy violation under the natural-language policy rules.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs the agent to use shell, network, environment, and local file operations (`scripts/ari.py setup/check/configure/...`) but does not declare any explicit tool scope or permission boundary. That creates an over-privileged integration surface where an agent runtime may grant broader capabilities than users expect, increasing the risk of unintended command execution, network access, or secret handling during normal use.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
1. 运行 `check`,确认账户、邮箱验证状态和可用积点。
2. 用户要 VOC / 评论分析报告时,默认运行 `voc <ASIN> --site <站点>`。
   **返回里有 `autoConfirmed: true` 就说明已经直接生成了**(1.4.5 起:服务端对前几次小额
   付费操作免确认,用户先拿到结果再谈钱),此时把报告讲给用户,并转述 `autoConfirmNote`
   (本次扣了多少、还剩几次免确认、之后会先问)。**不要在拿到结果后再补问「要不要生成」。**
3. 返回 `confirmationRequired: true` 才需要用户确认:报出 `totalCredits` 与余额,
Confidence
91% confidence
Finding
This workflow tells the agent to initiate `voc <ASIN>` by default, and the surrounding text makes clear that the service may auto-confirm and charge for small paid operations before any explicit per-action user approval. That is dangerous because a natural-language request for analysis can trigger billable side effects without a contemporaneous consent checkpoint in the agent, especially when the user may not understand the server-side auto-confirm policy.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
1. 运行 `check`,确认账户、邮箱验证状态和可用积点。
2. 用户要 VOC / 评论分析报告时,默认运行 `voc <ASIN> --site <站点>`。
   **返回里有 `autoConfirmed: true` 就说明已经直接生成了**(1.4.5 起:服务端对前几次小额
   付费操作免确认,用户先拿到结果再谈钱),此时把报告讲给用户,并转述 `autoConfirmNote`
   (本次扣了多少、还剩几次免确认、之后会先问)。**不要在拿到结果后再补问「要不要生成」。**
3. 返回 `confirmationRequired: true` 才需要用户确认:报出 `totalCredits` 与余额,
   用户同意后运行 `voc <ASIN> --site <站点> --confirm`。该命令会自动补齐采集、等待任务完成、
Confidence
90% confidence
Finding
The instruction to run `--confirm` after a minimal approval phrase, combined with prior default execution behavior, reduces the quality of user consent for paid actions. In an agent setting, terse confirmation handling can make accidental or ambiguous approval more likely, leading to unintended charges or actions against the user's account.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
用户只说自然语言。网页是补充视图(图表、分享链接、海报),不是把人送走的地方。

**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
Confidence
93% confidence
Finding
The skill explicitly says that when `autoConfirm: true` is returned, the agent should directly generate the report and not ask the user first. That normalizes autonomous spending behavior based on backend policy rather than user intent, which is risky in a tool-using agent because it weakens the human-in-the-loop control expected for billable or state-changing operations.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。
Confidence
87% confidence
Finding
Allowing the agent to change account-level `autoconfirm` settings based on conversational phrases can permanently alter future consent behavior, not just the current request. This is dangerous because a casual statement like 'don't ask next time' can reduce safeguards for subsequent paid actions, effectively expanding the agent's spending authority beyond a single transaction.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The display name, short description, and default prompt are all written in Chinese, which indicates the skill is presented in a single language without any visible user opt-in or documented locale limitation. This can violate language/locale policy when the skill is not clearly scoped to Chinese-speaking users or a China-specific deployment.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `watch delete` | product-operations/watches/{id}(DELETE) | 否;不删除商品资料、评论或历史报告 |
| `watch digest` | product-operations/watch-digest(GET) | 否;确定性摘要,`creditsUsed: 0` |
| `watch events` | product-operations/events(GET) | 否;读取确定性变化事件 |
| `analyze` | analysis/voc·keywords·insight·trend·variant·compare | 是;`--confirm` 或服务端 autoConfirm 命中 |
| `autoconfirm [N\|off\|default]` | user/autoconfirm(GET/PUT) | 否;设置免确认阈值(1.4.5) |
| `deepdive` | products + charts + reviews + reports + VOC quote/analysis | 默认否;`--confirm` 才分析 |
| `reports` / `report` | reports | 否 |
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
README.md:99