T09 · Insecure Skill Coding Practices
Error
- Location
- agentfinobs/dashboard.py:44
- Finding
- Unauthenticated Dashboard Exposes Financial Data on All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `agentfinobs/dashboard.py:44-83`, `agentfinobs/dashboard.py:132-134` **Related Data Definition**: `agentfinobs/types.py:89-106` **Vulnerability Type**: Unauthenticated network exposure and sensitive information disclosure **Risk Level**: High ### Vulnerable Code ```python def start(self, host: str = "0.0.0.0", port: int = 9400): """Start dashboard in a background daemon thread.""" dashboard = self # capture for handler closure class Handler(BaseHTTPRequestHandler): def do_GET(self): path = self.path.rstrip("/") routes = { "": dashboard._index, "/healthz": dashboard._healthz, "/metrics": dashboard._metrics_all, "/metrics/1h": dashboard._metrics_1h, "/metrics/24h": dashboard._metrics_24h, "/budget": dashboard._budget_status, "/alerts": dashboard._alerts, "/txs/recent": dashboard._recent_txs, "/anomaly/stats": dashboard._anomaly_stats, } handler_fn = routes.get(path) if handler_fn is None: self.send_error(404, "Not found") return self._json_response(handler_fn()) def _json_response(self, data): body = json.dumps(data, indent=2).encode() self.send_response(200) self.send_header("Content-Type", "application/json") self.send_header("Access-Control-Allow-Origin", "*") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) self._server = HTTPServer((host, port), Handler) ``` The transaction endpoint returns complete transaction dictionaries: ```python def _recent_txs(self) -> dict: txs = self.tracker.recent(50) return {"transactions": [tx.to_dict() for tx in txs]} ``` Those dictionaries include sensitive co ...[truncated 3098 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Change the default bind address to loopback: ```python def start(self, host: str = "127.0.0.1", port: int = 9400): ``` 2. Add an explicit `dashboard_host` parameter to `ObservabilityStack.create()` and require deliberate opt-in before permitting a non-loopback address. 3. Add authentication and authorization controls, such as a bearer token validated before route dispatch. Use constant-time token comparison. 4. Remove wildcard CORS. Disable CORS by default or allow only explicitly configured trusted origins. 5. Redact sensitive transaction fields from dashboard responses by default. In particular, make descriptions, tags, task IDs, and counterparties configurable or omitted unless explicitly requested. 6. Recommend TLS and authenticated reverse-proxy deployment when the dashboard must be remotely reachable. 7. Document that the dashboard contains sensitive financial data and must not be exposed directly to public or untrusted networks. 8. Add automated tests confirming that the default listener is loopback-only and that protected endpoints reject unauthenticated requests. ]]>
