Back to skill

Security audit

Ddzaishot

Security checks for vulnerabilities and agentic risk

Overview

The skill matches a Dou Dizhu game-assistant purpose, but it captures and stores full-screen images and can automate mouse clicks without enough scoping or safety guidance.

Install only if you are comfortable granting a game helper screen-capture and mouse-control capability. Close sensitive windows before scanning, avoid auto mode unless you have calibrated it and the game window is active, delete saved screenshots in logs when finished, and prefer a virtual environment with pinned dependency versions.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
src/screen.py:177
Finding
Full-Desktop Screenshots Are Persisted Without Data Minimization<![CDATA[ ## Vulnerability Details **File Location**: `src/screen.py:19-21`, `src/screen.py:158-168`, `src/screen.py:177-180`, and `src/main.py:128-129` **Vulnerability Type**: Excessive capture and plaintext local storage of potentially sensitive screen content **Risk Level**: Medium ### Vulnerable Code ```python def capture_full(self) -> np.ndarray: """Full-screen screenshot""" img = pyautogui.screenshot() return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) ``` ```python def scan(self) -> dict: """ Scan the game screen and return game state. """ image = self.capture.capture_full() return { 'my_cards': self.recognizer.recognize_cards(image, 'my_cards'), 'left_cards_count': self._count_cards(image, 'left_cards'), 'right_cards_count': self._count_cards(image, 'right_cards'), 'played_cards': self.recognizer.recognize_played_cards(image), 'landlord': self.recognizer.recognize_landlord(image), 'screenshot': image } ``` ```python def save_screenshot(self, path: str = "logs/screenshot.png"): """Save screenshot""" image = self.capture.capture_full() cv2.imwrite(path, image) ``` ```python # Save screenshot self.scanner.save_screenshot("logs/last_scan.png") print("\nScreenshot saved to logs/last_scan.png") ``` ### Technical Analysis The card recognizer only processes predefined game regions, but `capture_full()` captures the entire desktop. During an interactive scan, one full-screen image is captured for recognition and another full-screen image is captured and written to `logs/last_scan.png`. The persisted PNG is not encrypted, access-controlled by the application, automatically deleted, or governed by a retention policy. Consequently, unrelated information visible on other areas of the desktop can be collected and retained even though it is unnecessary for card recognition. Such content may include messages, email, notifications, account details, documents, or cr ...[truncated 1281 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Capture only the detected game window or the smallest regions needed for recognition: ```python image = self.capture.capture_region(game_x, game_y, game_width, game_height) ``` 2. Reuse the image already captured for recognition instead of taking a second screenshot: ```python def save_screenshot(self, image, path): cv2.imwrite(path, image) ``` 3. Crop the image before persistence so unrelated desktop content is excluded. 4. Make screenshot storage opt-in and clearly notify the user before writing an image. 5. Create screenshot files with restrictive owner-only permissions where supported. 6. Add automatic expiration or deletion of diagnostic screenshots. 7. Avoid returning the full screenshot in the scanner state unless a caller explicitly requests it. 8. Validate that the target window is present before capture to prevent recording the wrong desktop content. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Mutable and Unnecessarily Broad Third-Party Dependency Set<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6` and `SKILL.md:59-62` **Vulnerability Type**: Unpinned dependencies and unnecessary supply-chain exposure **Risk Level**: Low ### Vulnerable Code ```text opencv-python>=4.8.0 numpy>=1.24.0 pyautogui>=0.9.54 pillow>=10.0.0 mss>=9.0.0 keyboard>=0.13.5 ``` The installation instructions also recommend installing the same packages without version constraints: ```bash pip install opencv-python numpy pyautogui pillow mss keyboard ``` ### Technical Analysis All dependencies in `requirements.txt` use lower-bound constraints rather than exact reviewed versions. A future installation can therefore resolve to versions that did not exist when the project was audited. No lock file, package hashes, or trusted-index restrictions are provided. The documented direct installation command is less restrictive because it omits even the minimum versions. Package resolution consequently depends on the configured package index and the newest compatible packages available at installation time. The audit found no imports of `keyboard` or `mss` in the project source. In particular, `keyboard` provides global keyboard monitoring capabilities that are unnecessary for the implemented behavior. Installing unused packages expands the dependency graph and supply-chain attack surface without providing a functional benefit. This finding does not establish that any listed package is currently malicious. The risk arises from mutable dependency resolution, unnecessary components, and the absence of integrity verification. ### Attack Path 1. A user follows `SKILL.md` or installs `requirements.txt`. 2. Pip queries its configured package index and resolves versions that satisfy the broad constraints. 3. A compromised future package release, compromised configured index, or maliciously substituted distribution is selected. 4. Package-controlled code can run during installation or later when the dependency is imported. ...[truncated 623 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove dependencies not used by the source code, particularly `keyboard` and `mss`. 2. Pin all direct and transitive dependencies to reviewed exact versions. 3. Generate a lock file and include cryptographic hashes, for example with `pip-tools`: ```bash pip-compile --generate-hashes requirements.in pip-sync requirements.txt ``` 4. Change documentation to install from the locked requirements file rather than listing unconstrained packages: ```bash python -m pip install --require-hashes -r requirements.txt ``` 5. Use a trusted, explicitly configured package index and prevent fallback to untrusted indexes. 6. Review dependency updates before changing pins and run automated vulnerability scanning against the lock file. 7. Install dependencies in a dedicated virtual environment under a non-privileged user account. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (20)

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly describes automated screen capture, game-history logging, AI-driven inference, and mouse-click automation, but provides no warning about privacy, data retention, permissions, or the risks of controlling user input. This is dangerous because users may run the tool without understanding that it can capture on-screen sensitive information, store behavioral data, or interfere with normal system interaction.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill advertises '辅助出牌(可选)' and later references mouse calibration, which implies it may generate mouse/input events in a live session, but it does not clearly warn users about the risks of unintended clicks, focus issues, or interference with ongoing gameplay. In a tool that interacts with the screen and possibly controls input, lack of explicit disclosure and safety guidance increases the chance of harmful or unexpected actions during use.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code’s user-facing natural-language text and descriptions are entirely in Chinese, including the module description and method docstrings, with no indication that the skill is region-specific or that users can choose another language. The policy requires flagging language or locale constraints when they are imposed without opt-in or justification.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The skill's visible name, help text, prompts, and status messages are entirely in Chinese, and the interface does not offer the user any language or locale selection. Under the policy, hard-coding a specific language without opt-in is a natural-language policy violation unless the regional constraint is clearly documented and justified.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code enables an automatic mode that delegates gameplay actions to a mouse automation component (`self.auto_player.enabled = self.auto_mode`) and, when suggesting a play, can invoke automated play behavior without any explicit safety confirmation, scope limitation, or warning about controlling the user's input device. Even though the current call passes an empty list and appears simplified, the design clearly supports autonomous GUI interaction, which can misclick, interfere with other windows, or act on the user's behalf in ways the user may not fully anticipate.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This file's natural-language interface and documentation strings are entirely in Chinese, including the module description and class docstring. Under the stated policy, forcing a specific language without opt-in or justification is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This code captures the full screen and can persist screenshots to disk without any user-facing notice, consent flow, minimization, or access controls. Because full-screen images can contain unrelated sensitive information from other apps, notifications, credentials, or personal data, the feature creates a real privacy and data-exposure risk if invoked unexpectedly or by other components.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
All user-facing instructions and command guidance in this file are presented in Chinese, and the skill does not indicate that users may choose another language. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern unless the locale restriction is explicitly justified.

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8.0
numpy>=1.24.0
pyautogui>=0.9.54
pillow>=10.0.0
Confidence
96% confidence
Finding
The dependency is specified with a lower-bound range instead of an exact version, which makes builds non-reproducible and can allow installation of unexpected or newly compromised releases. In a security-sensitive skill, this increases supply-chain risk because the actual installed OpenCV package cannot be reliably audited or reproduced.

Unverifiable Dependency: opencv-python has 16 known advisory(ies) (CVE-2017-12864 (Integer Overflow or Wraparound in OpenCV); CVE-2017-12598 (Out-of-bounds Read in OpenCV ); CVE-2019-14493 (NULL Pointer Dereference in OpenCV.) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding
OpenCV has multiple known advisories, and because the manifest does not pin a concrete version, it is impossible to determine whether the installed release is vulnerable. This is dangerous because the project may silently resolve to an affected version, especially in fresh or rebuilt environments.

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8.0
numpy>=1.24.0
pyautogui>=0.9.54
pillow>=10.0.0
mss>=9.0.0
Confidence
96% confidence
Finding
Using an unpinned NumPy version allows the environment to resolve to different releases over time, undermining reproducibility and making vulnerability status difficult to verify. This creates a low-severity but real supply-chain exposure if a bad or incompatible release is pulled in.

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding
NumPy has known advisories, but the current requirement does not identify the exact version that will be installed. Without a pinned version, security review cannot confirm whether deployments are using a patched or vulnerable release.

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8.0
numpy>=1.24.0
pyautogui>=0.9.54
pillow>=10.0.0
mss>=9.0.0
keyboard>=0.13.5
Confidence
97% confidence
Finding
An unpinned pyautogui dependency permits installation of varying upstream releases, which can introduce unreviewed code changes into the runtime. Because pyautogui interacts with user input and desktop automation, supply-chain compromise of this package could be particularly risky in the broader skill context.

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8.0
numpy>=1.24.0
pyautogui>=0.9.54
pillow>=10.0.0
mss>=9.0.0
keyboard>=0.13.5
Confidence
96% confidence
Finding
The Pillow package is not pinned to a specific version, so the installed artifact may vary across installations and over time. That weakens assurance that the deployed version is free from known image-parsing flaws and increases general supply-chain uncertainty.

Unverifiable Dependency: pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding
Pillow has known historical vulnerabilities including serious image-processing issues, and the manifest leaves the installed version ambiguous. Because image libraries commonly process untrusted files, an unverified Pillow version can increase the chance of deploying a release affected by denial-of-service or even code-execution flaws.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy>=1.24.0
pyautogui>=0.9.54
pillow>=10.0.0
mss>=9.0.0
keyboard>=0.13.5
Confidence
95% confidence
Finding
Specifying mss with only a minimum version allows uncontrolled upgrades and non-reproducible environments. While not proof of a current exploit, this creates avoidable supply-chain and stability risk because the exact installed version is unknown until install time.

Unpinned Dependencies

Low
Category
Supply Chain
Content
pyautogui>=0.9.54
pillow>=10.0.0
mss>=9.0.0
keyboard>=0.13.5
Confidence
97% confidence
Finding
The keyboard package is unpinned, allowing future installations to pull arbitrary newer versions without review. In context, keyboard libraries can capture or synthesize input, so dependency uncertainty is more concerning than for a purely passive utility package.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The file’s user-facing natural-language content, including the module/class descriptions and returned status messages, is entirely in Chinese, which indicates a fixed language choice. Under the policy, locale or language constraints should either offer user opt-in/choice or be clearly documented as justified for a region-specific tool.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
This file’s natural-language documentation is entirely in Chinese, beginning with the top-level module description, and does not indicate that language is optional or configurable. Under the policy rule, forcing a specific language without user opt-in can be a locale/language policy issue even when it appears only in instructional text or comments.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
Docstrings, comments, and user-visible print messages are entirely in Chinese, and the file does not indicate that language is configurable or limited to a specific region-compliance context. This can violate language/locale policy when a skill implicitly enforces one language without user opt-in.

Static analysis

No suspicious patterns detected.