T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/web_preview.py:118
- Finding
- Unauthenticated Live Webcam Exposure on All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `scripts/web_preview.py`, lines 118-158 **Vulnerability Type**: Unauthenticated network exposure of sensitive webcam functionality **Risk Level**: High ### Vulnerable Code ```python class StreamHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': self._serve_html() elif self.path == '/stream': self._serve_stream() elif self.path == '/snapshot': self._take_snapshot() else: self.send_error(404) def _serve_html(self): self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() self.wfile.write(HTML_PAGE.encode()) def _serve_stream(self): self.send_response(200) self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=frame') self.end_headers() while camera.running: frame = camera.get_frame() if frame is not None: _, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 85]) self.wfile.write(b'--frame\r\n') self.send_header('Content-Type', 'image/jpeg') self.send_header('Content-Length', len(buffer)) self.end_headers() self.wfile.write(buffer.tobytes()) self.wfile.write(b'\r\n') time.sleep(0.033) def _take_snapshot(self): frame = camera.get_frame() if frame is not None: filename = camera.save_snapshot(frame) self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(f"Snapshot saved: {filename.name}".encode()) else: self.send_error(503, "No frame available") def log_message(self, format, *args): pass def main(): if not camera.start(): print("Fai ...[truncated 2129 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bind the preview server to the loopback interface by default: ```python server = HTTPServer(("127.0.0.1", 8081), StreamHandler) ``` 2. If remote access is genuinely required: - Require strong authentication for every endpoint. - Serve the application through TLS. - Restrict access with host firewall rules or an explicit IP allowlist. - Place the service behind a hardened reverse proxy. - Avoid exposing the camera service directly to untrusted networks. 3. Change snapshot creation to an authenticated `POST` endpoint rather than a `GET` endpoint. 4. Add CSRF protection when browser-based authenticated access is supported. 5. Apply rate limits and connection limits to streaming and snapshot endpoints. 6. Display the actual bind address at startup and clearly warn users when the service is configured for non-loopback access. 7. Consider disabling remote snapshot creation unless it is explicitly enabled through a secure configuration option. ]]>
