T09 · Insecure Skill Coding Practices
Note
- Location
- dashboard.py:43
- Finding
- Unauthenticated dashboard server binds to all network interfaces<![CDATA[ ## Vulnerability Details **File Location**: `dashboard.py:43-45` **Vulnerability Type**: Unauthenticated network service exposure **Risk Level**: Low ### Vulnerable Code ```python print(f"Starting dashboard on http://localhost:{PORT}") with socketserver.TCPServer(("", PORT), Handler) as httpd: httpd.serve_forever() ``` The exposed handler provides dashboard information without authentication: ```python def do_GET(self): if self.path == "/status": self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() data = {"capital": 10000, "return": 0, "positions": 0, "strategies": 10} self.wfile.write(json.dumps(data).encode()) elif self.path == "/strategies": self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() data = ["momentum", "mean_reversion", "breakout", "macd_cross", "supertrend", "rsi_extreme", "bollinger_bounce", "trend_following", "volatility_breakout", "ai_hybrid"] self.wfile.write(json.dumps(data).encode()) ``` ### Technical Analysis Passing an empty host string to `socketserver.TCPServer` binds the server to all available network interfaces, rather than only the loopback interface. This conflicts with the displayed `localhost` URL and may cause users to believe the dashboard is locally accessible only. The `/status` and `/strategies` endpoints have no authentication or authorization controls. The module also starts the server at import time because server initialization is not protected by an `if __name__ == "__main__":` guard. The currently returned information is static and not highly sensitive, which limits the immediate impact. However, the binding behavior creates an unsafe default and would expose any real account, position, or operational data subsequently added to these endpoints. ### Attack Path 1. A user starts `dashboard.py`, or another program imports it ...[truncated 820 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bind to the loopback interface by default: ```python HOST = "127.0.0.1" with socketserver.TCPServer((HOST, PORT), Handler) as httpd: httpd.serve_forever() ``` 2. Protect startup with a main guard to prevent side effects during import: ```python def main(): print(f"Starting dashboard on http://127.0.0.1:{PORT}") with socketserver.TCPServer(("127.0.0.1", PORT), Handler) as httpd: httpd.serve_forever() if __name__ == "__main__": main() ``` 3. If remote dashboard access is required, require authentication and authorization, terminate TLS through a trusted reverse proxy, and restrict access with host firewall rules. 4. Avoid returning account identifiers, balances, positions, trade history, or other operational information to unauthenticated clients. 5. Clearly document the listening address and security implications of enabling remote access. ]]>
