T09 Β· Insecure Skill Coding Practices
Error
- Location
- dashboard_api.py:102
- Finding
- Unauthenticated Dashboard Exposes Private Account Data and Workspace Files<![CDATA[ ## Vulnerability Details **File Location**: `dashboard_api.py:102-164` **Vulnerability Type**: Unauthenticated sensitive-data and arbitrary workspace-file exposure **Risk Level**: Critical ### Vulnerable Code ```python class H(BaseHTTPRequestHandler): def do_GET(self): if self.path.startswith('/api'): self._handle_api() else: self._serve_static() def _handle_api(self): try: data = get_account_data() except Exception as e: data = {'err': str(e), 'bal': 0.0, 'pnl': 0.0, 'pos': []} body = json.dumps(data).encode() self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Cache-Control', 'no-store') self.end_headers() self.wfile.write(body) def _serve_static(self): """Serve files from /root/.openclaw/workspace/, limited to that directory tree.""" if '..' in self.path: self.send_error(403, 'Forbidden') return if self.path == '/': file_path = '/root/.openclaw/workspace/index.html' else: file_path = '/root/.openclaw/workspace' + self.path if not os.path.isfile(file_path): self.send_error(404, 'Not Found') return mime = mimetypes.guess_type(file_path)[0] or 'application/octet-stream' try: with open(file_path, 'rb') as f: body = f.read() ``` ```python if __name__ == '__main__': server = ThreadedHTTPServer(('0.0.0.0', 8080), H) print('[dashboard_api] Listening on 0.0.0.0:8080') server.serve_forever() ``` ### Technical Analysis The dashboard binds to every network interface and implements no authentication or authorization. Any reachable client can call `/api` and receive private Binance account information, including balance, PnL, symbols, position dire ...[truncated 1831 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bind the service to `127.0.0.1` by default and expose it only through an authenticated reverse proxy with TLS. 2. Require authentication and authorization for `/api` and all static resources. 3. Serve files exclusively from a dedicated public-assets directory using canonical path validation. 4. Maintain an explicit file allowlist and reject dotfiles, configuration files, logs, caches, and symbolic links. 5. Remove `Access-Control-Allow-Origin: *`; configure an exact trusted origin if cross-origin access is required. 6. Return only the minimum dashboard fields needed and avoid exposing position amounts or entry details unnecessarily. 7. Add rate limiting, security logging, secure response headers, and network firewall restrictions. 8. Rotate Binance and Telegram credentials if this dashboard has ever been exposed publicly. ]]>
