Back to skill

Security audit

Amazon Listing 变化提醒

Security checks for vulnerabilities and agentic risk

Overview

This skill presents itself as a narrow Amazon listing-change watcher, but the bundled CLI exposes broader authenticated account, paid analysis, export, and auto-confirm controls.

Review before installing. The watch commands match the stated purpose, but the packaged CLI can also use the same ARI API key for broader account data access, paid analysis, exports, and confirmation-policy changes. Install only if you intend to trust this package as a general ARI account client, not just a listing-change alert tool, and prefer a scoped API key or a watch-only build if available.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

other

Warning
Location
scripts/ari.py:1683
Finding
Specialized Skill Bundles Unrelated Privileged API Capabilities## Vulnerability Details **File Location**: `scripts/ari.py:1683-1922` **Vulnerability Type**: Excessive capability scope and failure to enforce least functionality **Risk Level**: Medium The declared Skill is limited to deterministic Amazon listing-change watch operations, but its bundled executable also registers review collection, paid AI analysis, competitor management, exports, account operations, and other server-side mutation capabilities. Relevant command registrations include: ```python sub = ap.add_subparsers(dest="command", required=True) p.set_defaults(fn=cmd_setup) p.set_defaults(fn=cmd_configure) p.set_defaults(fn=cmd_check) p.set_defaults(fn=cmd_autoconfirm) p.set_defaults(fn=cmd_products) p.set_defaults(fn=cmd_collect) p.set_defaults(fn=cmd_reviews) p.set_defaults(fn=cmd_schedule) p.set_defaults(fn=cmd_competitors) p.set_defaults(fn=cmd_analyze) watch_sub = watch_parser.add_subparsers( dest="watch_command", required=True ) p.set_defaults(fn=cmd_watch_list) p.set_defaults(fn=cmd_watch_create) p.set_defaults(fn=cmd_watch_pause) p.set_defaults(fn=cmd_watch_resume) p.set_defaults(fn=cmd_watch_delete) p.set_defaults(fn=cmd_watch_digest) p.set_defaults(fn=cmd_watch_events) p.set_defaults(fn=cmd_operation_run) p.set_defaults(fn=cmd_voc) p.set_defaults(fn=cmd_deepdive) p.set_defaults(fn=cmd_alerts) p.set_defaults(fn=cmd_leaderboard) p.set_defaults(fn=cmd_workbench) p.set_defaults(fn=cmd_advise) ``` ### Technical Analysis `SKILL.md` declares a fixed `watch/listing` workflow whose intended operations are limited to listing watches and deterministic digests. However, `scripts/ari.py` is a general-purpose ARI client with substantially broader functionality. The executable does not enforce a specialized-Skill allowlist at its entry point. Consequently, possession of the configured ARI API key gives this package access to every command registered by the general client, ...[truncated 2148 chars]
Remediation
## Remediation Suggestions 1. Ship a dedicated watch-only executable containing only `setup`, narrowly scoped credential checks, and the documented `watch` subcommands. 2. Add a hard allowlist at the executable entry point for specialized distributions. Reject every top-level command other than those explicitly required by the Skill. 3. Separate the general-purpose ARI client into a different package that users must deliberately install. 4. Use API credentials with server-enforced scopes such as `watch:read` and `watch:write`, rather than relying only on client-side command restrictions. 5. Require explicit user confirmation for every watch mutation, including create, pause, resume, and delete, when invoked through an autonomous agent. 6. Disable account-level auto-confirm settings in specialized packages unless they are strictly required and clearly disclosed. 7. Add automated release tests that compare the declared workflow and capabilities in `_meta.json` and `skill-defaults.json` against the executable command registry. Fail packaging if unrelated commands are exposed. 8. Preserve the existing custom-base safeguard and restrictive API-key file permissions, as these appropriately reduce credential-redirection and local disclosure risks.
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 (19)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises shell, network, environment, and file-write capable workflows but does not declare permissions or boundaries. That creates a trust and review gap: an operator may invoke a skill that can access local secrets, make outbound requests, and write files without explicit disclosure or policy controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented purpose says this skill is limited to deterministic Amazon listing-change alerts, but the broader behavior includes credential handling, account operations, paid AI/LLM analysis, exports, streaming results, and other unrelated workflows. This mismatch is dangerous because users and automated reviewers may grant trust, credentials, or execution approval under a narrow description while the skill can perform much broader and potentially costly or sensitive actions.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The CLI exposes broad review collection, paid AI analysis, exports, workbench actions, and product-operations workflows far beyond the declared listing-change alert purpose. In a skill ecosystem, this is dangerous because users and supervising agents may grant trust based on the narrow manifest while the code can perform materially different, cost-incurring, data-processing actions.

Description-Behavior Mismatch

Critical
Confidence
99% confidence
Finding
The manifest says the skill does not call paid LLMs, but `run_analysis()` obtains quotes and executes paid analysis endpoints including SSE-backed AI generation. This mismatch can lead to unauthorized charges and unintended transmission of product/review data to remote AI services under false pretenses.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The skill is described as reminder-only and not modifying remote state, yet `cmd_autoconfirm` changes account-level behavior on the server by updating the user's auto-confirm threshold. That can silently alter future spending/authorization behavior and undermines the principle of a passive alerting tool.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The product-operations workflow engine introduces powerful remote analysis/execution capabilities unrelated to listing-change alerts. In context, this overreach increases the attack surface and the chance that an agent or user invokes costly or sensitive operations they did not expect this skill to possess.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
Local export/download functionality is not justified by a change-alert skill and writes server-returned data directly to arbitrary local paths chosen by arguments. While not inherently malicious, it expands the skill from passive alerting into local file-writing behavior that users and orchestration layers may not expect.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The module docstring states paid collection and AI analysis require explicit `--confirm`, but later code auto-confirms and executes billable actions when server policy allows. This deceptive contract is dangerous because higher-level agents may rely on the claim and trigger paid actions without obtaining real user consent.

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
96% confidence
Finding
This command allows the skill to configure account-level auto-confirm behavior, enabling future paid operations to run without per-action confirmation. In the context of a listing-change alert skill, that is an unjustified authority escalation over spending controls and remote account state.

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
97% confidence
Finding
This `PUT /api/v1/user/autoconfirm` call modifies remote account policy so future billable operations may proceed automatically. Because the skill is marketed as a reminder-only tool, this hidden ability is especially dangerous and can reduce user control over charges.

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
97% confidence
Finding
This `PUT /api/v1/user/autoconfirm` call modifies remote account policy so future billable operations may proceed automatically. Because the skill is marketed as a reminder-only tool, this hidden ability is especially dangerous and can reduce user control over charges.

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
97% confidence
Finding
This `PUT /api/v1/user/autoconfirm` call modifies remote account policy so future billable operations may proceed automatically. Because the skill is marketed as a reminder-only tool, this hidden ability is especially dangerous and can reduce user control over charges.

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
99% confidence
Finding
This logic flips `confirm` to true based on a server-provided `autoConfirm` flag and available balance, allowing paid AI analysis to execute without a fresh local confirmation. That bypasses the documented explicit-consent model and can lead to unanticipated charges and remote data processing.

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
98% confidence
Finding
Setting `auto_confirmed = True` records that the tool intentionally bypassed explicit confirmation for a paid action. This reinforces that the behavior is designed, not accidental, and contributes to unauthorized billing risk in context.

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
99% confidence
Finding
The conditional directly uses server policy to skip user confirmation for a paid analysis request. In a skill advertised as requiring explicit confirmation, this is a clear consent and billing-control violation.

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
99% confidence
Finding
This comment and surrounding logic explicitly implement first-run auto-confirm for combined collection plus VOC analysis, a billable workflow. In context, that means the skill can both collect data and invoke paid AI processing without explicit per-run consent.

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
99% confidence
Finding
The boolean expression enables automatic execution when server policy allows and balances are sufficient. This directly bypasses the stated confirmation requirement for a multi-step paid flow.

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
98% confidence
Finding
This line participates in deciding whether the command should proceed automatically despite missing explicit confirmation. It is part of a deliberate design that weakens user spending control.

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
98% confidence
Finding
This line participates in deciding whether the command should proceed automatically despite missing explicit confirmation. It is part of a deliberate design that weakens user spending control.

Static analysis

No suspicious patterns detected.