Back to skill

Security audit

我的二维码生成技能

Security checks for vulnerabilities and agentic risk

Overview

This QR-code skill matches its stated purpose, but it can automatically install Python packages when loaded and can persist sensitive QR contents as image files.

Review before installing. This skill is not clearly malicious, but the current version can modify the Python environment by running pip automatically and can leave sensitive QR payloads, such as WiFi passwords, as image files on disk. Prefer a version that declares pinned dependencies for explicit installation and asks for or clearly confirms save locations for sensitive QR codes.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Error
Location
agent.py:7
Finding
Unpinned Runtime Dependency Installation During Module Initialization## Vulnerability Details **File Location**: `agent.py`, lines 7-17 **Vulnerability Type**: Uncontrolled runtime package installation **Risk Level**: High **Vulnerable Code**: ```python def install_dependencies(): required_packages = ["qrcode", "pillow"] for package in required_packages: try: __import__(package) # Check whether the library is installed except ImportError: # Automatically install the missing library subprocess.check_call([sys.executable, "-m", "pip", "install", package]) # Initialization: install dependencies install_dependencies() ``` ### Technical Analysis The module invokes pip automatically during initialization whenever a dependency check fails. Package names are not constrained by version pins, integrity hashes, a lock file, or a trusted package index. Consequently, the code installed and executed by pip can change after the skill has been reviewed. The check for Pillow is also incorrect: Pillow exposes the `PIL` import namespace rather than `pillow`. Therefore, `__import__("pillow")` normally raises `ImportError` even when Pillow is already installed, potentially causing pip to be invoked every time the module is initialized. The installation mechanism is also unreliable for genuinely missing dependencies because `qrcode` and `PIL` are imported at lines 1-2 before `install_dependencies()` runs. If either initial import fails, execution terminates before the installation function can repair the environment. This does not mitigate the supply-chain risk when the top-level imports succeed but the incorrect `pillow` check triggers installation. ### Attack Path 1. An attacker compromises, controls, or redirects the Python package index configured in the execution environment. 2. The skill module is imported. 3. The `pillow` import check fails because the package's actual import namespace is `PIL`, or another dependency check fails ...[truncated 855 chars]
Remediation
## Remediation Suggestions - Remove all automatic package installation from module import and runtime execution paths. - Declare dependencies in a dedicated dependency manifest and install them during an explicit, isolated deployment step. - Pin exact reviewed versions of `qrcode` and `Pillow`. - Use a lock file or hash-verified installation mode, such as pip's `--require-hashes`. - Restrict installation to an explicitly trusted package index and disable unintended fallback indexes. - Build and scan dependencies in CI before deployment rather than modifying the environment when the skill loads. - If a diagnostic dependency check remains necessary, check Pillow with `import PIL` and return a clear error without invoking pip. - Run the deployed skill under a least-privileged account and in an environment where installed dependencies are immutable.

T09 · Insecure Skill Coding Practices

Warning
Location
agent.py:20
Finding
Unbounded QR Image Dimensions Permit Resource Exhaustion## Vulnerability Details **File Location**: `agent.py`, lines 20-55 **Vulnerability Type**: Missing input bounds leading to denial of service **Risk Level**: Medium **Vulnerable Code**: ```python async def generate_qr(text: str, size: int = 300, color: str = "black", save_path: str = None) -> str: """ Generate a QR code, save it to the specified path, and return the result. Parameters: text: QR-code content size: QR-code dimensions in pixels color: Fill color save_path: Destination path """ # Validate required content if not text or text.strip() == "": return "Generation failed: QR-code content is required" # Process the default destination path if not save_path: if sys.platform == "win32": save_path = os.path.join(os.environ["USERPROFILE"], "Desktop", "qr_code.png") else: save_path = os.path.expanduser("~/Desktop/qr_code.png") try: qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=10, border=4, ) qr.add_data(text.strip()) qr.make(fit=True) img = qr.make_image(fill_color=color, back_color="white") img = img.resize((size, size), Image.Resampling.LANCZOS) ``` ### Technical Analysis The `size` parameter is used directly as both image dimensions without runtime type or range validation. Python type annotations are not enforcement mechanisms, so callers can supply any value accepted by the downstream Pillow operation. Image memory consumption grows approximately with the square of the requested dimension. A sufficiently large positive integer can therefore cause substantial allocation and resampling work. Pillow may reject some extreme dimensions, but relying on downstream errors does not provide a safe application-level resource limit. Repeated large ...[truncated 1061 chars]
Remediation
## Remediation Suggestions - Validate that `size` is an integer and reject booleans or other coercible types. - Enforce a conservative minimum and maximum, such as 64 through 4096 pixels, based on measured deployment capacity. - Reject invalid values before generating or resizing any image. - Limit the length of `text` as a complementary defense against excessive QR-code generation work. - Apply request-level timeouts, concurrency limits, and memory constraints around image-processing workloads. - Return a stable validation error rather than exposing raw downstream exception details. - Add tests for negative, zero, non-integer, boundary, and extremely large dimensions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill explicitly supports encoding potentially sensitive content such as WiFi credentials and saves the resulting QR image to disk, defaulting to the desktop, but it does not warn the user about local persistence or exposure to others with access to the device. This can lead to unintended disclosure of secrets because the QR image itself becomes a durable artifact containing credentials or personal data.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
A QR generation skill should not need to install software dynamically during execution, yet this file does so automatically. That expands the skill's capabilities from simple data processing to host modification and remote code retrieval, which is dangerous in agent or sandboxed environments.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
required_packages = ["qrcode", "pillow"]
    for package in required_packages:
        try:
            __import__(package)  # 检查库是否已安装
        except ImportError:
            # 自动安装缺失的库
            subprocess.check_call([sys.executable, "-m", "pip", "install", package])
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
__import__(package)  # 检查库是否已安装
        except ImportError:
            # 自动安装缺失的库
            subprocess.check_call([sys.executable, "-m", "pip", "install", package])

# 初始化:安装依赖库
install_dependencies()
Confidence
96% confidence
Finding
This code launches pip via subprocess from within the skill, causing package installation side effects on the host environment. Even though the package names are hardcoded, executing package management automatically can modify the runtime unexpectedly, pull untrusted code from package indexes, and violate least-privilege expectations for a QR generation utility.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
Running pip subprocesses automatically at import time means merely loading the module can trigger network access and system changes without user knowledge or consent. This is especially risky for agent skills, where import-time behavior should be side-effect free and predictable.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The natural-language description and all user examples are written in Chinese, with no indication that other languages are supported or that the user may choose their preferred language. This can amount to a language/locale policy issue when a skill implicitly forces one language without opt-in or documented justification.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
Natural-language strings and comments presented to the user are in Chinese, and there is no indication that other languages are supported or that the locale restriction is intentional and justified. This can violate language/locale policy when users are not given an opt-in or alternative.

Static analysis

No suspicious patterns detected.