Back to skill

Security audit

Amazon 移动端 Listing 优化

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real ARI listing-analysis integration, but it can spend credits and change persistent account settings with less per-action confirmation than users may expect.

Review this skill before installing. It is not showing evidence of deception, exfiltration, destructive remote code, or hidden persistence, but only install it if you are comfortable giving it ARI account access, local key storage, local file export ability, and authority to run paid ARI workflows. Set auto-confirm to ask every time if you want explicit approval before spending credits, confirm the marketplace for each paid task, and avoid using --out paths that point at existing or sensitive files.

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
Export Function Allows Unrestricted File Overwrite and Symlink Following<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ari.py`, lines 1474–1475 **Vulnerability Type**: Arbitrary file overwrite through an attacker-influenced export path **Risk Level**: Medium ### Vulnerable Code ```python with open(dest, "wb") as fh: fh.write(body) ``` The destination is derived directly from the `--out` command-line argument: ```python dest = args.out or ("ari_report_%d.%s" % ( args.report_id, "html" if fmt == "html" else "md" )) emit(request_download( "/api/v1/export/reports/%d" % args.report_id, {"format": fmt}, dest ), args.compact) ``` The same behavior applies to review exports: ```python dest = args.out or ("ari_reviews_%s.csv" % args.asin.upper()) emit(request_download( "/api/v1/export/reviews", {"asin": args.asin.upper(), "site": args.site}, dest ), args.compact) ``` ### Technical Analysis The export handler accepts an unrestricted path through `--out` and opens it using Python's `"wb"` mode. This mode creates a file when it does not exist and truncates an existing file before writing. The implementation does not: - Restrict exports to a dedicated directory. - Reject absolute paths or parent-directory traversal. - Check whether the destination already exists. - Detect symbolic links. - Use `O_NOFOLLOW` where supported. - Create the file exclusively with `O_EXCL`. - Ask for confirmation before replacing an existing file. Consequently, any file writable by the account running the Skill can be replaced with server-provided export content. Symbolic links are followed by the regular `open()` call, producing a time-of-check/time-of-use and link-following risk in shared or attacker-controlled directories. This flaw is classified as `T09: Insecure Skill Coding Practices`. It does not independently provide privilege escalation: file-system access remains constrained by the operating-system privileges of the Skill process. ### Attack Path A practical exploitation sequence is: 1. An atta ...[truncated 2118 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use a dedicated export directory by default** Resolve all generated exports beneath a private user directory, such as `~/.ari/exports`, and create it with restrictive permissions. 2. **Require explicit opt-in for arbitrary paths** Treat `--out` as a potentially destructive option. Reject absolute paths and paths that resolve outside the designated export directory unless the user supplies a separate explicit override. 3. **Do not overwrite existing files by default** Open 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) ``` Return an error if the destination already exists. If overwrite support is required, add a clearly documented `--force` option and require explicit user confirmation. 4. **Reject symbolic links and non-regular destinations** Validate the parent directory and destination with `os.lstat()`. Reject symbolic links, device files, FIFOs, sockets, and other non-regular files. 5. **Canonicalize and validate the destination** Resolve the destination and approved export directory with `pathlib.Path.resolve()`, then verify that the destination remains inside the approved directory. 6. **Use atomic replacement only after validation** Download to a newly created temporary file in the same trusted directory, flush and synchronize it, and then rename it atomically. Do not place temporary files in shared directories. 7. **Run with least privilege** Document that the CLI must not be run as root or another privileged service account. This limits the damage possible from path manipulation or accidental overwrites. ]]>
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 (27)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill declares no permissions while explicitly instructing use of shell execution, network access, local file writes, and environment/API-key handling. This mismatch weakens platform trust boundaries and can cause users or hosting systems to authorize a skill without understanding that it can execute commands, persist credentials locally, and reach external services.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The public description says the skill is only for mobile Listing expression diagnosis, but the body authorizes a much broader operational surface: paid collection, reporting, exports, competitor management, scheduling, watch management, and account-setting changes. This kind of scope expansion is dangerous because users may invoke the skill under a narrow mental model while the agent performs materially different actions with billing, data export, and persistent account effects.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The documentation states that when no marketplace is specified, the skill will assume the U.S. site by default. That can cause the agent to act on the wrong regional dataset without explicit user consent, leading to incorrect analysis, unintended charges, or disclosure of account-specific information tied to a different marketplace than the user intended. In this skill’s context, the risk is real because many operations involve paid collection/analysis and region-specific balances, permissions, and product data.

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
95% confidence
Finding
This section instructs the agent to run a paid VOC flow by default and to accept service-side auto-confirmed charges without first obtaining transaction-specific consent from the user in the session. Even if the backend permits auto-confirm, the skill is authorizing financially impactful actions based on implicit defaults, which is risky for delegated agents.

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
94% confidence
Finding
The workflow states that after a default run, only some responses require confirmation, meaning the agent may already have triggered chargeable collection/generation before asking the user. This creates a consent gap for paid actions and increases the chance of unintended charges or unwanted data processing.

Autonomous Decision Making

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

**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
Confidence
95% confidence
Finding
The skill explicitly says that when the backend reports autoConfirm, the agent should directly generate results and not ask the user. For an agent with purchasing/billing side effects, this is dangerous because it normalizes silent execution of paid actions and undermines informed consent.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。
Confidence
91% confidence
Finding
This same instruction block encourages the agent to persistently modify confirmation behavior ('off', numeric threshold, default) from natural-language requests. In a delegated execution environment, persistent changes to spending controls are security-relevant because they affect future transactions beyond the current task.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
- 报价需要确认时,只说两个数:这次多少积点、余额多少,然后等用户一个「好」。采集是**固定单价**:直接说「15 积点/页 × 3 页 = 45 积点」,不要说成「预计 / 最多」——价格不会浮动;商品评论不够这么多页时只收实际采到的页数,差额自动退回(`pricingNote` 已写好这句)。不要罗列参数。
Confidence
91% confidence
Finding
This same instruction block encourages the agent to persistently modify confirmation behavior ('off', numeric threshold, default) from natural-language requests. In a delegated execution environment, persistent changes to spending controls are security-relevant because they affect future transactions beyond the current task.

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
83% confidence
Finding
This line instructs the agent to proactively propose enabling a weekly schedule after completing a report, with only a lightweight consent step afterward. In context, the skill already spans billing and account changes, so proactive upsell into recurring actions increases the risk of users being funneled into persistent paid workflows from a narrowly advertised diagnostic skill.

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
88% confidence
Finding
This documents that `analyze` may execute paid operations when server-side `autoConfirm` rules are met, allowing the agent workflow to trigger billable analysis without an explicit per-action user confirmation. In an agent setting, that creates a real autonomous-action risk because the model may proceed from documentation cues and spend credits or initiate collection/analysis on the user's behalf.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `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 | 否 |
| `alerts` | alerts(`--mark-read` 时 alerts/read) | 否 |
Confidence
92% confidence
Finding
This repeated finding is still valid because the same line exposes a persistent control that lowers confirmation requirements for future billable actions. Persistent safety-setting changes are more dangerous than a one-off action because they silently alter later agent behavior.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `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 | 否 |
| `alerts` | alerts(`--mark-read` 时 alerts/read) | 否 |
Confidence
92% confidence
Finding
This repeated finding is still valid because the same line exposes a persistent control that lowers confirmation requirements for future billable actions. Persistent safety-setting changes are more dangerous than a one-off action because they silently alter later agent behavior.

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
90% confidence
Finding
This section explicitly states that `voc` may directly generate paid work under server-side no-confirm rules and automatically perform collection, waiting, analysis, and archiving. That is a concrete autonomous workflow with billing and data-processing side effects, making it a true agentic-action vulnerability if the skill is allowed to follow these instructions without explicit user approval.

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
87% confidence
Finding
The presence of `autoConfirm` in quote fields encourages downstream logic to treat eligibility for auto-confirm as permission to proceed. In an autonomous agent, exposing this as a normal decision variable increases the chance that the model interprets backend allowance as user consent, leading to unintended billable 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 remains valid because the same line provides machine-usable parameters for autonomous spending decisions. The risk is not just the field name but the workflow implication that the agent may infer an allowed spending envelope and act within it automatically.

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 remains valid because the same line provides machine-usable parameters for autonomous spending decisions. The risk is not just the field name but the workflow implication that the agent may infer an allowed spending envelope and act within it automatically.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
`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
86% confidence
Finding
`autoConfirmNote` and related quote metadata can normalize the idea that direct execution is expected when allowed by the service. While lower impact than an execution command itself, this still contributes to unsafe autonomous behavior by framing backend policy as sufficient authorization.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
并附 `web.report` / `web.product` 网页链接。

- `voc`: Markdown VOC 报告,SSE 聚合后在 `data.content`,并归档。
Confidence
90% confidence
Finding
The same execution semantics are repeated here and preserve the same risk: backend auto-confirm can be mistaken for front-end user authorization. In an API-keyed commercial service, unintended execution directly maps to cost and account-side effects, so this is a real vulnerability in the skill context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
并附 `web.report` / `web.product` 网页链接。

- `voc`: Markdown VOC 报告,SSE 聚合后在 `data.content`,并归档。
Confidence
90% confidence
Finding
The same execution semantics are repeated here and preserve the same risk: backend auto-confirm can be mistaken for front-end user authorization. In an API-keyed commercial service, unintended execution directly maps to cost and account-side effects, so this is a real vulnerability in the skill context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
另有(1.4.5):`autoConfirm`(true = 服务端首次体验策略允许免确认直接生成)、
`autoConfirmMaxCredits`(免确认单次上限,采集 + 报告合计)、`autoConfirmRemaining`(还剩几次)、
`autoConfirmNote`、`webUrl`(该产品的网页报告页)。`sampleCap` / `degraded` 表示 Free 样本封顶与轻量模型。
`voc` / `analyze` 在 autoConfirm 命中时会直接生成,返回 `autoConfirmed: true` 与 `autoConfirmNote`,
并附 `web.report` / `web.product` 网页链接。

- `voc`: Markdown VOC 报告,SSE 聚合后在 `data.content`,并归档。
Confidence
90% confidence
Finding
The same execution semantics are repeated here and preserve the same risk: backend auto-confirm can be mistaken for front-end user authorization. In an API-keyed commercial service, unintended execution directly maps to cost and account-side effects, so this is a real vulnerability in the skill context.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
if not ok(quote):
        return quote
    q_data = data_of(quote) or {}
    # 首次体验免确认(服务端策略 skill.autoConfirm):前几次小额直接生成,不再多问一轮。
    auto_confirmed = False
    if not confirm and q_data.get("autoConfirm") and q_data.get("sufficient"):
        confirm = True
Confidence
91% confidence
Finding
The analysis path can flip confirm=True automatically when the server returns autoConfirm and sufficient, causing a paid analysis to run even when the local invocation did not include --confirm. In an agent context, this weakens the explicit-consent boundary for billable operations and could lead to unintended charges if upstream orchestration assumes '--confirm absent' always means quote-only.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
return quote
    q_data = data_of(quote) or {}
    # 首次体验免确认(服务端策略 skill.autoConfirm):前几次小额直接生成,不再多问一轮。
    auto_confirmed = False
    if not confirm and q_data.get("autoConfirm") and q_data.get("sufficient"):
        confirm = True
        auto_confirmed = True
Confidence
91% confidence
Finding
This variable marks that the client auto-approved a paid action without a local --confirm argument. In a skill invoked by another agent, that can surprise the caller and violate least astonishment around billing and action authorization.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
q_data = data_of(quote) or {}
    # 首次体验免确认(服务端策略 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:
Confidence
91% confidence
Finding
The conditional trusts a server-provided autoConfirm bit to override local non-confirmed execution. That creates a policy inversion where remote state can authorize a billable action that the immediate caller did not explicitly confirm.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
if plan is not None and plan["balance"]["note"]:
        combined_quote["siteNote"] = plan["balance"]["note"]
    combined_quote["webUrl"] = analysis_quote.get("webUrl")
    # 首次体验免确认:服务端 autoConfirm=true 且「采集 + 报告」合计不超过单次上限时,直接跑完。
    # 在聊天里多问一句「确认吗」,很多用户就不回了——先让他拿到结果。
    auto_max = int(analysis_quote.get("autoConfirmMaxCredits") or 0)
    auto_confirmed = (not args.confirm and bool(analysis_quote.get("autoConfirm"))
Confidence
92% confidence
Finding
The one-shot VOC workflow can auto-confirm a combined collection-plus-analysis purchase when the server says autoConfirm is enabled and the total is within threshold. Because this can spend credits on both data collection and analysis without a local --confirm, it is more impactful than a simple read-only action.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
combined_quote["webUrl"] = analysis_quote.get("webUrl")
    # 首次体验免确认:服务端 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:
Confidence
92% confidence
Finding
This condition allows an omitted --confirm to be overridden by server-advertised autoConfirm for a billable multi-step workflow. In agent use, that can trigger unintended purchases and actions on behalf of the user.

Static analysis

No suspicious patterns detected.