Back to skill

Security audit

亚马逊选品调研 · 评论验证需求

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real ARI Amazon review research integration, but it can spend ARI credits through service-side auto-confirm rules without fresh per-operation approval.

Review the billing behavior before installing. Install only if you are comfortable linking an ARI account, storing an ARI API key locally, and allowing some small or preauthorized analyses to run and deduct credits automatically. To reduce risk, tell the agent to use quote-only mode or set autoconfirm off before paid work.

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

Server-Controlled Auto-Confirmation Permits Charges Without Explicit Per-Operation Approval

Content
View full analysis

Vulnerability Details

File Location: scripts/ari.py:1145-1149, scripts/ari.py:1378-1385; supporting instructions in SKILL.md:92-95 and SKILL.md:145-148
Vulnerability Type: Improper authorization of paid operations
Risk Level: Medium

Technical Analysis

The CLI normally uses the local --confirm flag as the authorization boundary for paid analysis. However, run_analysis promotes an unconfirmed invocation to a confirmed operation when the remote quote response contains autoConfirm and sufficient:

python
# 首次体验免确认(服务端策略 skill.autoConfirm):前几次小额直接生成,不再多问一轮。
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": "用户确认后追加 --confirm 才会生成并扣点。"},
            "links": links()}

The combined VOC workflow similarly allows a server response to authorize paid collection and analysis without the caller supplying --confirm:

python
# 首次体验免确认:服务端 autoConfirm=true 且「采集 + 报告」合计不超过单次上限时,直接跑完。
# 在聊天里多问一句「确认吗」,很多用户就不回了——先让他拿到结果。
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

The Skill instructions explicitly activate this behavior rather than requiring a local confirmation:

text
返回里有 `autoConfirmed: true` 就说明已经直接生成了
...
报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。

...[truncated 1998 chars]

Remediation
View remediation

Remediation Suggestions

  • Never change the effective confirm value based solely on fields returned by the remote service.
  • For every chargeable operation, return the quote and require an explicit local --confirm before submitting collection or analysis requests.
  • If standing authorization is required, store a user-configured local spending policy and enforce it independently of the service response.
  • Bind confirmation to the exact operation, account, ASIN, site, quoted amount, and request identifier. Requote or request confirmation again if any of these values change.
  • Treat autoConfirm, autoConfirmMaxCredits, and similar response fields as informational only.
  • Update SKILL.md to require confirmation before the first chargeable operation rather than instructing the Agent to proceed based on server policy.
  • Add tests proving that analyze and voc cannot reach paid submission paths without --confirm, regardless of quote-response fields.
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 (68)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- CLI:本 Skill 目录下的 `scripts/ari.py`。在 Skill 根目录执行,例如

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The script makes authenticated and unauthenticated HTTPS requests to an external service, which is a material capability in a skill execution environment. If network access is undeclared, the skill can exfiltrate metadata or act on behalf of the user without the expected transparency, even though this implementation restricts requests to the official domain.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The script makes authenticated and unauthenticated HTTPS requests to an external service, which is a material capability in a skill execution environment. If network access is undeclared, the skill can exfiltrate metadata or act on behalf of the user without the expected transparency, even though this implementation restricts requests to the official domain.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The script makes authenticated and unauthenticated HTTPS requests to an external service, which is a material capability in a skill execution environment. If network access is undeclared, the skill can exfiltrate metadata or act on behalf of the user without the expected transparency, even though this implementation restricts requests to the official domain.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire natural-language content of the file is written in Chinese, with no indication that language choice is optional or that the skill is region-specific. Under the stated policy, forcing a specific language/locale without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · CHANGELOG.md (reported line 23)May include surrounding context.

md
- 能力层收窄:44 个专属包不再只是「声明窄」,包体 `scripts/ari.py` 同时按各自契约裁剪。
  构建期用 AST 删除文档未承诺的命令、它们的解析器注册块,以及只被它们引用的辅助函数与
  常量;专属包因此不再包含 `export`(任意路径写文件)、`autoconfirm`(撤销逐次确认)、
  `workbench`(改写差评处理状态)、`alerts`(标记预警已读)、`competitors`、`schedule`、
  `voc` / `analyze` / `charts` / `deepdive` 等母版命令。
- 新增运行期兜底闸:专属包在包内写入 `allowedCommands` 白名单,`ari.py`

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · scripts/ari.py (reported line 1806)May include surrounding context.

python
- 能力层收窄:44 个专属包不再只是「声明窄」,包体 `scripts/ari.py` 同时按各自契约裁剪。
  构建期用 AST 删除文档未承诺的命令、它们的解析器注册块,以及只被它们引用的辅助函数与
  常量;专属包因此不再包含 `export`(任意路径写文件)、`autoconfirm`(撤销逐次确认)、
  `workbench`(改写差评处理状态)、`alerts`(标记预警已读)、`competitors`、`schedule`、
  `voc` / `analyze` / `charts` / `deepdive` 等母版命令。
- 新增运行期兜底闸:专属包在包内写入 `allowedCommands` 白名单,`ari.py`

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · scripts/ari.py (reported line 1808)May include surrounding context.

python
- 能力层收窄:44 个专属包不再只是「声明窄」,包体 `scripts/ari.py` 同时按各自契约裁剪。
  构建期用 AST 删除文档未承诺的命令、它们的解析器注册块,以及只被它们引用的辅助函数与
  常量;专属包因此不再包含 `export`(任意路径写文件)、`autoconfirm`(撤销逐次确认)、
  `workbench`(改写差评处理状态)、`alerts`(标记预警已读)、`competitors`、`schedule`、
  `voc` / `analyze` / `charts` / `deepdive` 等母版命令。
- 新增运行期兜底闸:专属包在包内写入 `allowedCommands` 白名单,`ari.py`

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

This workflow allows a potentially billable operation to proceed automatically when the backend marks it as auto-confirmed, without obtaining an explicit per-action confirmation from the user in the current session. That creates an unauthorized-action risk: the agent may trigger paid analysis or collection based on prior account settings or server policy rather than fresh user consent.

Content

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

md
1. 运行 `check`,确认账户、邮箱验证状态和可用积点。
2. 用户要 VOC / 评论分析报告时,默认运行 `voc <ASIN> --site <站点>`。
   **返回里有 `autoConfirmed: true` 就说明已经直接生成了**(1.4.5 起:服务端对前几次小额
   付费操作免确认,用户先拿到结果再谈钱),此时把报告讲给用户,并转述 `autoConfirmNote`
   (本次扣了多少、还剩几次免确认、之后会先问)。**不要在拿到结果后再补问「要不要生成」。**
3. 返回 `confirmationRequired: true` 才需要用户确认:报出 `totalCredits` 与余额,

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

The skill instructs the agent to run a confirm flag after a minimal acknowledgment, which reduces friction around paid execution and can lead to actions being taken without clear, informed consent. In an agent setting, this is risky because the model is empowered to spend credits and launch workflows on behalf of the user.

Content

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

md
1. 运行 `check`,确认账户、邮箱验证状态和可用积点。
2. 用户要 VOC / 评论分析报告时,默认运行 `voc <ASIN> --site <站点>`。
   **返回里有 `autoConfirmed: true` 就说明已经直接生成了**(1.4.5 起:服务端对前几次小额
   付费操作免确认,用户先拿到结果再谈钱),此时把报告讲给用户,并转述 `autoConfirmNote`
   (本次扣了多少、还剩几次免确认、之后会先问)。**不要在拿到结果后再补问「要不要生成」。**
3. 返回 `confirmationRequired: true` 才需要用户确认:报出 `totalCredits` 与余额,
   用户同意后运行 `voc <ASIN> --site <站点> --confirm`。该命令会自动补齐采集、等待任务完成、

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The instruction to directly generate results whenever autoConfirm is returned delegates spending authority to service-side policy instead of the active user's immediate approval. That weakens human-in-the-loop controls and can cause unwanted paid actions, especially if the user does not understand that analysis may execute and deduct credits immediately.

Content

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

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

**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
94% confidence
Finding

Allowing the agent to change account-wide auto-confirm thresholds on the user's behalf can permanently weaken future approval controls beyond the current task. This is more dangerous than a one-off execution because it modifies the user's safety posture and may enable subsequent unattended spending.

Content

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

md
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
92% confidence
Finding

The pattern encourages streamlined approvals based on a terse acknowledgment and fixed-price messaging, which can normalize spending with insufficient disclosure. In an autonomous agent context, reducing confirmation to a minimal 'OK' increases the chance of accidental authorization for paid operations.

Content

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

md
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。

**新手(`check` 返回 `autoConfirm.mode` 为 `first_runs` / `free_small`,或问"然后呢")**

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file states that report language should follow the user, but then specifies that the CLI default is zh and instructs non-Chinese replies to explicitly pass --language en or similar. This creates a language-default policy issue because Chinese is imposed unless the agent actively overrides it, rather than offering a neutral or user-confirmed default.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.