T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:45
- Finding
- Unredacted Sensitive Flow Data Sent to a Third-Party Service and Exposed in Agent Output<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:45-55`, `SKILL.md:151-177`, and `SKILL.md:267-278` **Vulnerability Type**: Sensitive-data exposure through external transmission and unredacted diagnostic output **Risk Level**: Medium ### Complete Code Snippet ```python import json, urllib.request MCP_URL = "https://mcp.flowstudio.app/mcp" MCP_TOKEN = "<YOUR_JWT_TOKEN>" def mcp(tool, **kwargs): payload = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": tool, "arguments": kwargs}}).encode() req = urllib.request.Request(MCP_URL, data=payload, headers={"x-api-key": MCP_TOKEN, "Content-Type": "application/json", "User-Agent": "FlowStudio-MCP/1.0"}) try: resp = urllib.request.urlopen(req, timeout=120) ``` ```python # Get the root failing action's full inputs and outputs root_action = err["failedActions"][-1]["actionName"] detail = mcp("get_live_flow_run_action_outputs", environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID, actionName=root_action) if len(detail) > 1: print(f"{root_action} returned {len(detail)} repetitions; inspect iteration indexes") out = detail[0] if detail else {} print(f"Action: {out.get('actionName')}") print(f"Status: {out.get('status')}") # For HTTP actions, the real error is in outputs.body if isinstance(out.get("outputs"), dict): status_code = out["outputs"].get("statusCode") body = out["outputs"].get("body", {}) print(f"HTTP {status_code}") print(json.dumps(body, indent=2)[:500]) # Error bodies are often nested JSON strings — parse them if isinstance(body, dict) and "error" in body: err_detail = body["error"] if isinstance(err_detail, str): err_detail = json.loads(err_detail) print(f"Error: {err_detail.get('message', err_detail)}") # For expression errors, the error is in the error field if out.get("error"): print(f"Error: {out['e ...[truncated 3365 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require explicit operator authorization before retrieving complete runtime inputs or outputs, especially for production flows. 2. Use a metadata-first diagnostic process: - Retrieve action names, status, timestamps, and error codes first. - Request detailed payloads only for the minimum set of actions needed. - Prefer selected fields over complete input and output objects. 3. Add recursive redaction before printing or returning data. At minimum, mask keys matching: - `authorization` - `cookie` and `set-cookie` - `token`, `access_token`, and `refresh_token` - `api-key`, `apikey`, and `x-api-key` - `password`, `secret`, and `client_secret` - `connectionString` 4. Redact bearer tokens and credential-like values by pattern, even when their enclosing field names are unknown. 5. Replace direct `print()` calls with a safe rendering function that applies redaction, field allowlisting, and bounded output. 6. Do not include full runtime payloads in agent prompts or persistent logs by default. 7. Store the MCP JWT in a protected environment variable or secret manager rather than encouraging users to place it directly in source code. 8. Document the FlowStudio trust boundary, data handling, retention policy, and the types of production data that may be transmitted. 9. Prefer test or sanitized runs when investigating issues that do not require production payloads. ]]>
