Back to skill

Security audit

亚马逊卖点提炼 · 购买动因挖掘

Security checks for vulnerabilities and agentic risk

Overview

This Amazon review skill is mostly disclosed, but it can trigger paid analysis, ongoing monitoring, and account confirmation changes in ways users should review carefully before installing.

Install only if you want a broad ARI Amazon review-operations assistant, not just a one-off selling-point extractor. Before use, set the account to ask before every paid action if you do not want auto-confirmed credit spending, be careful with monitoring/schedule/watch requests because they persist, and avoid custom export paths unless you are sure they are safe to overwrite.

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:1474
Finding
Arbitrary File Overwrite and Symbolic-Link Following During Export## Vulnerability Details **File Location**: `scripts/ari.py:1444-1475` and `scripts/ari.py:1929` **Vulnerability Type**: Unrestricted file overwrite and symbolic-link following **Risk Level**: Medium ### Vulnerable Code ```python def request_download(path, params, dest): """Download a non-JSON response to a local file.""" query = {"method": "GET", "path": path, "params": {k: v for k, v in (params or {}).items() if v not in (None, "")}, "payload": None} url = base_url() + path if query["params"]: url += "?" + urllib.parse.urlencode(query["params"], doseq=True) headers = { "Authorization": "Bearer " + require_key(), "User-Agent": user_agent() } try: req = urllib.request.Request(url, headers=headers, method="GET") with urllib.request.urlopen(req, timeout=TIMEOUT_SEC) as resp: note_release(resp.headers) ctype = resp.headers.get("Content-Type", "") body = resp.read() if "application/json" in ctype: out = json.loads(body.decode("utf-8", errors="replace")) if isinstance(out, dict): out["_query"] = query return out tail = body[-300:].decode("utf-8", errors="replace") if "# export error:" in tail: return error_obj( "ARI_EXPORT_ERROR", 200, tail.split("# export error:", 1)[1].strip(), "Export failed before completion; no file was written.", query ) with open(dest, "wb") as fh: fh.write(body) ``` The destination is exposed directly through a command-line argument: ```python p.add_argument("--out", help="Output file path; defaults to an automatically generated path") ``` ### Technical Analy ...[truncated 2359 chars]
Remediation
## Remediation Suggestions 1. Save exports in a dedicated, user-owned export directory by default. 2. Resolve and validate the destination with `pathlib.Path.resolve()` and reject paths outside the approved directory unless the user explicitly authorizes them. 3. Refuse to overwrite existing files by default. Add an explicit `--overwrite` option if replacement is required. 4. Create new files atomically and exclusively: ```python flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL if hasattr(os, "O_NOFOLLOW"): flags |= os.O_NOFOLLOW fd = os.open(dest, flags, 0o600) with os.fdopen(fd, "wb") as fh: fh.write(body) ``` 5. Verify that the resolved parent is a directory owned or trusted by the current user. 6. Download into a securely created temporary file in the destination directory, flush and synchronize it, and then perform an atomic rename after all response validation succeeds. 7. If overwriting is explicitly enabled, use platform-appropriate symbolic-link protections and revalidate the destination immediately before replacement.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (34)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares no permissions while the content clearly instructs use of shell execution, network access, environment variables, and local file writes. This mismatch weakens platform oversight and informed consent because a reviewer or user may assume the skill is low-risk while it can access credentials, call external services, and persist data locally.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The advertised purpose is narrow selling-point extraction, but the skill instructions cover a much broader operational surface: billing/credits, account settings, report export, review retrieval, competitor management, monitoring, and multiple paid analysis workflows. That scope expansion is dangerous because it enables actions a user would not reasonably expect from the description, including paid operations and persistent account changes.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill is described as an Amazon selling-point extraction tool, but the CLI exposes much broader capabilities: product operations, watch management, exports, workbench actions, competitor management, and monitoring changes. This scope mismatch is dangerous because agents or users may grant trust and credentials based on the narrow advertised purpose, while the code can perform unrelated stateful and potentially billable actions against the backend.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The code can mutate server-side state unrelated to selling-point extraction, including scheduling collection, creating/deleting watches, changing review workflow status, configuring autoconfirm behavior, and modifying competitor relationships. In a skill ecosystem, this violates least privilege and increases the chance of unauthorized operational changes or surprise charges if an agent invokes capabilities that users did not reasonably expect from the skill description.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill metadata presents a narrow 'selling-point extraction' purpose, but the documentation exposes a much broader operational toolkit including collection, monitoring, exports, alerts, paid analyses, and account-affecting workflows. This scope mismatch can mislead users and host platforms into granting or invoking capabilities they did not reasonably expect, increasing the risk of over-privileged use and unintended paid or persistent actions.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The guide emphasizes low-star review diagnosis, dissatisfaction analysis, and improvement workflows rather than the advertised selling-point extraction from positive reviews. This functional mismatch can cause the agent to collect and analyze broader review data than users intended, producing off-purpose outputs and increasing the chance of privacy, billing, or consent surprises.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The documentation includes long-term monitoring, scheduling, watch creation, and recurring collection features that exceed the reasonable expectations of a selling-point extraction skill. Persistent automation materially raises risk because it can create ongoing charges, continued data collection, and durable account state changes from what appears to be a one-off analysis tool.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
Alerts, workbench access, and AI-generated complaint replies/appeals are unrelated to selling-point extraction and grant the skill influence over sensitive business-response workflows. In the wrong context, this can lead to unauthorized access to account-level review operations or automated generation of customer-facing responses the user did not intend this skill to handle.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Benchmarking, leaderboard queries, and competitor-binding radar features broaden the skill into category intelligence and competitive monitoring beyond its stated purpose. This increases exposure to unnecessary data access and user confusion about what the skill may do, especially where competitor tracking can trigger ongoing collection or strategic analysis outside the original request.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
The opening branding describes a general Amazon review intelligence assistant focused on dissatisfaction, purchase motives, and improvement opportunities, which contradicts the manifest's narrower selling-point-extraction positioning. This inconsistency weakens informed consent and makes it easier for the skill to justify broader analysis and actions than users or reviewers would expect from its declared role.

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
94% confidence
Finding
This workflow authorizes the agent to invoke `voc` by default and accept server-side auto-confirmed paid generation without a fresh user confirmation in-session. Even if the backend permits it, the agent is still performing a potentially chargeable action based on implicit rather than explicit consent, which can surprise users and spend credits unintentionally.

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 skill directs the agent to proceed with automated collection, waiting, and report generation after minimal confirmation handling. Because these are state-changing and potentially billable actions, compressing consent to a simplified flow increases the risk of misunderstanding, unintended charges, and overbroad execution on behalf of the user.

Autonomous Decision Making

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

**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
Confidence
95% confidence
Finding
The instruction to directly generate results when `autoConfirm: true` encourages the agent to treat backend policy as a substitute for user intent. In a conversational agent context, that creates a real risk of autonomous spending and action execution without sufficiently specific, contemporaneous user authorization.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。
Confidence
88% confidence
Finding
Allowing the agent to change the account's `autoconfirm` setting is a privileged account-management action that can alter future consent behavior beyond the current task. Although the text says to do so only when the user asks, this still expands the skill from analysis into account policy modification and can reduce safeguards for later transactions.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。
Confidence
88% confidence
Finding
Allowing the agent to change the account's `autoconfirm` setting is a privileged account-management action that can alter future consent behavior beyond the current task. Although the text says to do so only when the user asks, this still expands the skill from analysis into account policy modification and can reduce safeguards for later transactions.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。

**新手(`check` 返回 `autoConfirm.mode` 为 `first_runs` / `free_small`,或问"然后呢")**
- 报告讲完只推一个下一步,附接口返回的成本,不写死月费用。用户同意再 `schedule --set weekly`。
- 不解释命令名,不列功能清单。用户问「还能做什么」时按他的产品状态给一条建议,不超过三句。
Confidence
84% confidence
Finding
The recommendation to propose and then, upon user agreement, enable weekly scheduling introduces persistent background collection and recurring cost/state changes. In context this is more dangerous than a one-time analysis because it creates an ongoing monitoring relationship and future charges if the agent interprets brief assent too loosely.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
voc B0... --site amz_us 是完整 VOC 的入口:先取得报价,已有足够评论时使用当前分析价格;
数据不足时合并采集与分析费用。符合服务端免确认规则且总额不超过上限时可能直接生成,
返回 autoConfirmed。否则返回 confirmationRequired,取得用户同意后追加 --confirm,
自动完成必要采集、等待、分析和归档。只读询价应使用 quote / collect 报价入口。

`collect --asin B0... --site amz_us --pages 3` 只返回报价;确认后追加
Confidence
84% confidence
Finding
This section explicitly states that `voc` may directly generate a paid result when service-side auto-confirm rules match, which can allow an agent to trigger billable collection/analysis without an immediate per-action confirmation step. In an agent setting, that increases the risk of unintended charges or actions if user intent is ambiguous or prompts are misinterpreted.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
先调用 `quote --type ...`。报价字段:
`type, basePrice, price, sampledReviews, totalReviews, balance, sufficient`,
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
Confidence
85% confidence
Finding
Documenting an `autoConfirm` quote field is not dangerous by itself, but in this skill context it exposes a path for agents to interpret a quote response as permission to proceed automatically with paid analysis. That can undermine meaningful user consent and lead to unintended spend or unauthorized task execution.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
先调用 `quote --type ...`。报价字段:
`type, basePrice, price, sampledReviews, totalReviews, balance, sufficient`,
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
并附 `web.report` / `web.product` 网页链接。
Confidence
87% confidence
Finding
This duplicate finding points to the same direct-execution behavior under `autoConfirm`. The danger is not malicious logic but insufficient guardrails around autonomous paid actions in an agent context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
先调用 `quote --type ...`。报价字段:
`type, basePrice, price, sampledReviews, totalReviews, balance, sufficient`,
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
并附 `web.report` / `web.product` 网页链接。
Confidence
87% confidence
Finding
This duplicate finding points to the same direct-execution behavior under `autoConfirm`. The danger is not malicious logic but insufficient guardrails around autonomous paid actions in an agent context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
}


def cmd_autoconfirm(args):
    """免确认阈值:不带参数=查看;`autoconfirm 50`=50 积点以内不问;`autoconfirm off`=每次都问;`autoconfirm default`=恢复默认。"""
    value = (args.value or "").strip().lower()
    if value:
Confidence
94% confidence
Finding
The skill exposes a command to change autoconfirm thresholds, allowing future paid actions to proceed without an explicit per-operation confirmation. In an agent setting this is risky because it modifies the user's billing safety controls, potentially enabling downstream autonomous charges outside the narrow selling-point use case.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
def cmd_autoconfirm(args):
    """免确认阈值:不带参数=查看;`autoconfirm 50`=50 积点以内不问;`autoconfirm off`=每次都问;`autoconfirm default`=恢复默认。"""
    value = (args.value or "").strip().lower()
    if value:
        if value in ("off", "ask", "0"):
Confidence
94% confidence
Finding
This logic parses values that can disable prompts or set automatic spending thresholds. In the context of an agent-integrated skill, changing these settings can have persistent billing consequences beyond the current task.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
def cmd_autoconfirm(args):
    """免确认阈值:不带参数=查看;`autoconfirm 50`=50 积点以内不问;`autoconfirm off`=每次都问;`autoconfirm default`=恢复默认。"""
    value = (args.value or "").strip().lower()
    if value:
        if value in ("off", "ask", "0"):
Confidence
94% confidence
Finding
This logic parses values that can disable prompts or set automatic spending thresholds. In the context of an agent-integrated skill, changing these settings can have persistent billing consequences beyond the current task.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
def cmd_autoconfirm(args):
    """免确认阈值:不带参数=查看;`autoconfirm 50`=50 积点以内不问;`autoconfirm off`=每次都问;`autoconfirm default`=恢复默认。"""
    value = (args.value or "").strip().lower()
    if value:
        if value in ("off", "ask", "0"):
Confidence
94% confidence
Finding
This logic parses values that can disable prompts or set automatic spending thresholds. In the context of an agent-integrated skill, changing these settings can have persistent billing consequences beyond the current task.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
limit = int(value)
            except ValueError:
                emit(error_obj("ARI_BAD_ARGUMENT", 0, "参数不对",
                               "用法:autoconfirm 50(50 积点以内不问)/ autoconfirm off(每次都问)/ autoconfirm default(恢复默认)"),
                     args.compact)
                return
        out = request_json("PUT", "/api/v1/user/autoconfirm", {"limit": limit})
Confidence
95% confidence
Finding
The code performs a PUT to /api/v1/user/autoconfirm, directly mutating server-side billing confirmation preferences. This is dangerous because once changed, later billable operations may execute with reduced user oversight, making accidental or agent-driven charges more likely.

Static analysis

No suspicious patterns detected.