Back to skill

Security audit

Product Price Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill is a small local price-tracking helper with disclosed local storage, though its docs overstate automation and its default /tmp storage is weak.

Install only if you are comfortable with a simple local JSON-based tracker. Prefer setting PRICE_DB_FILE and PRICE_SCREENSHOT_DIR to a private user-owned directory, run it without elevated privileges, and verify product names before using --remove. Do not expect fully automatic price scraping or notifications without additional agent/tool automation.

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/monitor_price.py:14
Finding

Predictable Shared Temporary Paths Permit Symlink Attacks and State Tampering

Content
View full analysis

Vulnerability Details

File Location: scripts/monitor_price.py, lines 14-44
Vulnerability Type: Unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

python
# 数据文件路径
DB_FILE = os.environ.get("PRICE_DB_FILE", "/tmp/price_monitor_db.json")
SCREENSHOT_DIR = os.environ.get("PRICE_SCREENSHOT_DIR", "/tmp/price_screenshots")
python
def _ensure_directories(self):
    """确保数据目录存在"""
    try:
        self.screenshot_dir.mkdir(parents=True, exist_ok=True)
    except Exception as e:
        print(f"⚠️  创建截图目录失败: {e}")
python
def save_data(self):
    """保存价格数据库"""
    try:
        with open(self.db_file, 'w', encoding='utf-8') as f:
            json.dump(self.data, f, indent=2, ensure_ascii=False)
    except Exception as e:
        print(f"❌ 保存数据库失败: {e}")
        return False
    return True

Technical Analysis

The Skill stores its database and screenshot directory under fixed, globally predictable names in the shared /tmp directory. The database is opened directly in truncating write mode without checking whether the destination is a symbolic link or regular file. The implementation also does not securely create the file, validate its ownership, enforce restrictive permissions, or use an atomic replacement operation.

On systems where applicable symbolic-link protections are absent, disabled, or bypassed by the execution context, another local user can pre-create /tmp/price_monitor_db.json as a symbolic link. A subsequent database save can follow that link and truncate or overwrite another file writable by the Skill's effective user. Even when operating-system symlink protections block this exact technique, predictable shared storage still permits pre-creation, denial of service, and unauthorized manipulation where filesystem permissions allow it.

Directly truncating the database also makes updates non-atomic. Process interruption or concurrent ...[truncated 1902 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace shared fixed /tmp paths with a private, user-owned state directory, such as $XDG_STATE_HOME/price-monitor or ~/.local/state/price-monitor.
  2. Create the state directory with permissions 0700 and database files with permissions 0600.
  3. Before reading or writing, verify that the destination is a regular file owned by the expected user and reject symbolic links.
  4. Where supported, securely open files using flags such as O_NOFOLLOW, O_CREAT, and O_EXCL.
  5. Write JSON to a securely created temporary file in the same directory, flush and synchronize it, and then atomically replace the database using os.replace().
  6. Add file locking or another concurrency-control mechanism to prevent simultaneous processes from losing updates or corrupting the database.
  7. Validate custom paths supplied through PRICE_DB_FILE and PRICE_SCREENSHOT_DIR, and fail closed when ownership or permission checks do not pass.
  8. Update documentation to recommend execution as an unprivileged user rather than using a hard-coded /root installation path.
Vulnerability Patterns
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

描述将该技能表述为可自动监控价格、搜索价格、追踪历史并进行变动提醒的完整工具。但实际代码主要是一个本地JSON数据库管理和报告脚本。它能保存产品元数据、记录历史价格(前提是外部系统传入 price_data)、比较新旧价格并在控制台打印变化,还能生成简单报告。关键差异在于:1)没有任何内置网络访问、浏览器操作或搜索实现;2)没有自动执行监控的调度机制;3)没有真正的提醒/通知功能,只是控制台输出;4)用户通过CLI无法直接记录价格,核心监控链路依赖外部Agent。因此,声明的核心能力相比代码实际行为明显夸大,属于描述与行为不一致。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README presents all operational instructions, examples, and user-facing descriptions exclusively in Chinese, with no indication that other languages are supported or that Chinese is an optional locale. Per SQP-3, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises commands that read environment variables and write to local files, but it does not declare any explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this can cause the skill to operate with broader ambient authority than reviewers or orchestrators expect, increasing the chance of unintended file access or data persistence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file contains user-facing natural-language content primarily in Chinese, including the description, usage guidance, examples, and cautions, but does not indicate that the language is optional or provide an alternative locale. That creates a locale policy concern because the skill effectively forces a specific language for use and comprehension without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file describes a --remove command that deletes a monitored product entry, but it does not warn users that the action removes stored tracking data. For markdown files, SQP-2 applies when the skill description omits warnings about behaviors that could affect user data or system state.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.