Back to skill

Security audit

Amazon 竞品周报

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it gives an agent broad paid ARI account capabilities that can spend credits, change future confirmation settings, and write local export files beyond the narrow weekly competitor-report promise.

Review this before installing if you do not want an agent to spend ARI credits under account auto-confirm rules, change future confirmation thresholds, manage monitoring, or write exports to arbitrary local paths. Prefer using it only with explicit per-action confirmations and avoid granting broad natural-language permission such as 'do it automatically under 50 credits'.

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

Warning
Location
scripts/ari.py:1169
Finding
Specialized workflow restrictions can be overridden through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ari.py:1169-1171` and `scripts/ari.py:1647-1651` **Vulnerability Type**: Specialized workflow scope bypass **Risk Level**: Medium ### Vulnerable Code ```python def operation_payload(args): defaults = operation_defaults() workflow = (getattr(args, "workflow", None) or defaults.get("workflow") or "").strip() focus = (getattr(args, "focus", None) or defaults.get("focus") or "").strip() ``` The command-line parser exposes the overriding arguments: ```python def add_operation_args(parser, confirm=False): parser.add_argument("--asin", required=True) parser.add_argument("--site", default="amz_us", choices=SITES) parser.add_argument("--workflow") parser.add_argument("--focus") parser.add_argument("--competitor") parser.add_argument("--request-id", default="") ``` ### Technical Analysis The specialized Skill declares an immutable `weekly/competitor` workflow in `skill-defaults.json`, `SKILL.md`, and `references/operation-workflow.md`. However, `operation_payload()` gives command-line values precedence over those configured defaults. Consequently, the purportedly fixed workflow is not enforced as a local security boundary. An agent, user, or injected instruction can supply a different `--workflow` and `--focus`. The subsequent capability check only verifies that the ARI service supports the requested combination; it does not verify that the combination belongs to this specialized Skill. This does not bypass the server's account permissions or the explicit `--confirm` requirement. Nevertheless, it allows the package to perform supported paid operations outside its declared purpose and violates least-functionality expectations for a specialized Skill. ### Attack Path 1. The Skill is invoked for its declared competitor weekly-report function. 2. An attacker-controlled instruction or mistaken agent action supplies alternate `--workflow` and `--focus` values. 3. `operat ...[truncated 997 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat the values in `skill-defaults.json` as mandatory in specialized builds. 2. Remove `--workflow` and `--focus` from the specialized command-line interface, or reject values that do not exactly match the configured contract. 3. Distinguish specialized and generic builds explicitly rather than inferring behavior from optional defaults. 4. Add a local validation step before any quote or execution request: ```python def operation_payload(args): defaults = operation_defaults() configured_workflow = str(defaults.get("workflow") or "").strip() configured_focus = str(defaults.get("focus") or "").strip() supplied_workflow = str(getattr(args, "workflow", None) or "").strip() supplied_focus = str(getattr(args, "focus", None) or "").strip() if configured_workflow and supplied_workflow not in ("", configured_workflow): return None, error_obj( "ARI_WORKFLOW_OVERRIDE_BLOCKED", 0, "This specialized Skill does not permit workflow overrides." ) if configured_focus and supplied_focus not in ("", configured_focus): return None, error_obj( "ARI_FOCUS_OVERRIDE_BLOCKED", 0, "This specialized Skill does not permit focus overrides." ) workflow = configured_workflow or supplied_workflow focus = configured_focus or supplied_focus ``` 5. Have the service verify the Skill channel against an allowlisted workflow/focus combination so that a modified client cannot bypass the local restriction. 6. Add regression tests confirming that alternate workflow and focus values are rejected before a network request is sent. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ari.py:1474
Finding
Export destination permits arbitrary overwrite of user-writable files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ari.py:1474-1475` and `scripts/ari.py:1930-1933` **Vulnerability Type**: Unrestricted file write and symlink-following overwrite **Risk Level**: Medium ### Vulnerable Code The downloaded response is written directly to the caller-controlled destination: ```python with open(dest, "wb") as fh: fh.write(body) ``` The export command accepts an unrestricted output path: ```python p = sub.add_parser("export", parents=[common]) p.add_argument("--asin") p.add_argument("--report-id", type=int) p.add_argument("--out") p.set_defaults(fn=cmd_export) ``` ### Technical Analysis The `--out` argument can identify any path writable by the operating-system user running the Skill. The destination is opened in `wb` mode, which truncates an existing file before writing the downloaded export. The implementation does not: - Restrict output to a dedicated export directory. - Require confirmation before replacing an existing file. - Reject symbolic links. - Use exclusive file creation. - Verify that the resolved destination remains inside an approved directory. - Perform an atomic temporary-file write followed by a controlled rename. Python's normal `open()` behavior follows symbolic links. Therefore, a path that appears to be an ordinary export file can redirect the write to another user-writable target. ### Attack Path 1. An attacker influences the export command or convinces the agent to use a crafted `--out` path. 2. The path directly names a sensitive user-writable file, or names a symbolic link pointing to one. 3. The CLI authenticates to ARI and retrieves a valid export. 4. `open(dest, "wb")` follows the path and truncates the target. 5. The target is replaced with CSV, Markdown, or HTML export content. 6. Configuration, scripts, or other files writable by the current user may be corrupted or replaced. Exploitation requires the ability to influence the command arguments and a successful authorized exp ...[truncated 896 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Save exports under a dedicated directory such as `~/ARI/exports` by default. 2. Resolve the requested destination with `Path.resolve()` and verify that it remains under the approved export directory. 3. Reject symbolic-link destinations and validate every relevant parent directory. 4. Use exclusive creation so that existing files are not silently replaced: ```python from pathlib import Path export_root = Path.home() / "ARI" / "exports" export_root.mkdir(parents=True, exist_ok=True) destination = (export_root / requested_name).resolve() root = export_root.resolve() if root not in destination.parents: raise ValueError("The export path is outside the approved directory.") if destination.exists(): raise FileExistsError("The destination already exists.") with destination.open("xb") as fh: fh.write(body) ``` 5. If arbitrary destinations are a required advanced feature, require explicit overwrite confirmation and clearly display the resolved absolute path. 6. Write to a securely created temporary file in the same approved directory, flush and synchronize it, and then atomically rename it. 7. Consider using `os.open()` with `O_CREAT | O_EXCL | O_NOFOLLOW` where supported. 8. Add tests covering path traversal, absolute paths, existing files, symbolic links, and destinations outside the approved export directory. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (26)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises extensive shell, network, environment, and file-write capabilities but does not declare permissions, preventing effective policy enforcement and informed user/admin review. In this skill’s context, those capabilities include API key setup/storage and execution of paid or state-changing remote operations, so the hidden capability surface is materially risky rather than merely documentary.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared purpose is a narrow weekly competitor report, but the instructions authorize a much broader operational surface: credential setup, report generation, collection, monitoring, exports, alerts, watch management, and multiple paid analyses. This mismatch can cause overbroad activation and user consent confusion, increasing the chance that the agent performs sensitive, billable, or state-changing actions the user did not intend when invoking this specific skill.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The natural-language trigger examples are broad enough to match ordinary analysis requests, which makes this specialized skill likely to activate when the user may have intended a safer or more limited tool. Because this skill can lead into paid collection, monitoring, and account-affecting workflows, ambiguous activation expands the blast radius of a casual prompt.

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 instruction permits the skill to proceed with paid report generation whenever the backend marks the action as auto-confirmed, even if the user did not provide a fresh, explicit confirmation in the current conversation. In a billing-sensitive context, relying on server-side auto-confirm behavior weakens user-consent guarantees and can produce unwanted charges or actions.

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
92% confidence
Finding
The workflow defaults to running `voc` for user requests about VOC/comment analysis, and the instruction states the command may automatically collect data, wait, generate a report, and save it once confirmation rules are satisfied. That combines interpretation of broad user intent with a potentially billable, state-changing action, which is dangerous when prompts are ambiguous or when consent is inferred too loosely.

Autonomous Decision Making

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

**确认与扣点**
- 报价返回 `autoConfirm: true` 时直接生成,不要再问「要不要」。生成后一句话交代:本次扣了多少、
  还剩几次免确认(或「免费版小额不问」)。策略由服务端决定:免费版小额不问;付费版前几次不问,之后先问。
- 用户说「以后别问了 / 50 以内直接做」→ 运行 `autoconfirm 50`;说「以后每次先问我」→ `autoconfirm off`;
  说「恢复默认」→ `autoconfirm default`。这是唯一需要你代用户设置的东西,设完复述一句当前规则。
Confidence
95% confidence
Finding
The skill explicitly tells the agent to generate paid outputs automatically when the quote response says `autoConfirm: true`, and not to ask the user again. This is a direct delegation of spending authority to backend policy rather than the current user interaction, increasing the risk of unauthorized or surprising charges.

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
This same instruction couples relaxed confirmation UX with persistent `autoconfirm` changes, making it easier for a conversational misunderstanding to broaden future autonomous spending. In context, the skill supports many billable operations, so modifying confirmation thresholds has meaningful downstream security and financial implications.

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
This same instruction couples relaxed confirmation UX with persistent `autoconfirm` changes, making it easier for a conversational misunderstanding to broaden future autonomous spending. In context, the skill supports many billable operations, so modifying confirmation thresholds has meaningful downstream security and financial implications.

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
84% confidence
Finding
The reference explicitly allows paid analysis commands to execute when a server-side autoConfirm rule is triggered, meaning the agent may initiate billable operations without an explicit per-action user confirmation. In an agent setting, this weakens user-consent boundaries and can lead to unauthorized charges or unintended data collection if the agent treats autoConfirm as sufficient authorization.

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
88% confidence
Finding
Exposing an autoconfirm setting through the skill creates a path for the agent to alter a user's long-term confirmation policy, which can silently broaden future autonomous spending. Because this changes persistent account behavior rather than just a single request, misuse could enable repeated billable actions without meaningful consent.

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
88% confidence
Finding
Exposing an autoconfirm setting through the skill creates a path for the agent to alter a user's long-term confirmation policy, which can silently broaden future autonomous spending. Because this changes persistent account behavior rather than just a single request, misuse could enable repeated billable actions without meaningful consent.

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
85% confidence
Finding
This section states that VOC generation may directly proceed and complete collection, waiting, analysis, and archiving when server-side no-confirm rules match. In an agent workflow, that permits a multi-step paid operation with data collection side effects to run without contemporaneous user approval, increasing the risk of unauthorized spend and unintended processing.

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
80% confidence
Finding
The quote response includes autoConfirm metadata that can be interpreted by an agent as permission to execute immediately. While the field itself is informational, in this skill context it materially increases the chance that the agent will skip an explicit confirmation step for paid actions.

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
80% confidence
Finding
The documentation says voc/analyze will directly generate when autoConfirm is hit, returning autoConfirmed true. In a system where an agent is entrusted with API keys, this creates an unsafe autonomy pattern because billing and report generation can occur without an immediate user decision tied to that specific action.

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
80% confidence
Finding
The documentation says voc/analyze will directly generate when autoConfirm is hit, returning autoConfirmed true. In a system where an agent is entrusted with API keys, this creates an unsafe autonomy pattern because billing and report generation can occur without an immediate user decision tied to that specific action.

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
79% confidence
Finding
Advertising remaining autoConfirm capacity and thresholds may encourage logic that opportunistically spends available autonomous actions. The danger is not the field itself but that it facilitates agent-side decisioning about when to trigger paid operations without the user explicitly consenting each time.

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
79% confidence
Finding
The autoConfirm note and direct-generation behavior reinforce a pattern where billable analysis may proceed automatically once quote conditions match. In this skill's context, which is supposed to run only after explicit confirmation and completed quoting, that undermines the intended safety boundary.

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
79% confidence
Finding
The autoConfirm note and direct-generation behavior reinforce a pattern where billable analysis may proceed automatically once quote conditions match. In this skill's context, which is supposed to run only after explicit confirmation and completed quoting, that undermines the intended safety boundary.

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
79% confidence
Finding
The autoConfirm note and direct-generation behavior reinforce a pattern where billable analysis may proceed automatically once quote conditions match. In this skill's context, which is supposed to run only after explicit confirmation and completed quoting, that undermines the intended safety boundary.

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
90% confidence
Finding
The analysis flow can flip from quote-only to charge-and-run when the server returns autoConfirm=true and sufficient balance, even if the caller did not pass --confirm. In an agent setting, this weakens the explicit-consent barrier for paid actions and can lead to unintended charges if upstream orchestration misjudges user intent.

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
90% confidence
Finding
Setting auto_confirmed=True records that the tool proceeded with a paid action without local confirmation from the current invocation. In this skill context, which is meant to be used by agents, that creates a real risk of silent spending based on server policy rather than immediate user approval.

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
90% confidence
Finding
This conditional is the control point that bypasses the normal 'quote then confirm' workflow for analysis commands. Because the tool can incur charges, implicit confirmation is dangerous in agent-mediated environments where command construction may be indirect or ambiguous.

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-click VOC workflow can automatically proceed with both collection and analysis charges when server-provided autoConfirm conditions are met, despite no --confirm from the caller. Because this can combine multiple billable steps, the impact is higher than a simple quote display and can surprise users in agent-driven use.

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 expression computes an auto-confirm path for a bundled paid operation using balance and threshold checks, enabling execution without direct confirmation in the current invocation. In a skill intended for active triggering by an agent, that erodes consent guarantees around spending.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
# 首次体验免确认:服务端 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")
Confidence
90% confidence
Finding
The branch structure causes lack of --confirm to return a quote only when auto_confirmed is false; if auto_confirmed is true, execution continues. That means server/account state can silently override the local confirmation requirement for a paid workflow.

Static analysis

No suspicious patterns detected.