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. ]]>
