T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fxusd_morpho.py:460
- Finding
- Untrusted remote market metadata controls approval spenders and transaction destinations## Vulnerability Details **File Location**: `scripts/fxusd_morpho.py:214-232`, `scripts/fxusd_morpho.py:460-507`, `scripts/fxusd_morpho.py:553-557`, `scripts/fxusd_morpho.py:664-687`, and `scripts/fxusd_morpho.py:1078-1151` **Vulnerability Type**: Insufficient validation of execution-critical remote data **Risk Level**: High ### Vulnerable Code The Morpho GraphQL response is accepted directly: ```python def request_graphql(query: str, variables: dict[str, Any]) -> Any: last_error: Exception | None = None payload = json.dumps({"query": query, "variables": variables}).encode("utf-8") for delay in (0.0, 0.4, 1.0): if delay: time.sleep(delay) request = urllib.request.Request( GRAPHQL_URL, data=payload, headers={ "Content-Type": "application/json", "Accept": "application/json", "User-Agent": USER_AGENT, }, method="POST", ) try: with urllib.request.urlopen(request, timeout=20) as response: decoded = json.loads(response.read().decode("utf-8")) if decoded.get("errors"): raise ValueError(f"GraphQL error: {decoded['errors']}") return decoded["data"] ``` Remote metadata supplies the contract destination: ```python def normalize_market(market: dict[str, Any]) -> dict[str, Any]: state = market.get("state") or {} collateral_asset = market.get("collateralAsset") or {} loan_asset = market.get("loanAsset") or {} morpho_blue = market.get("morphoBlue") or {} oracle = market.get("oracle") or {} warnings = market.get("warnings") or [] collateral_symbol = collateral_asset.get("symbol") risk_class, risk_summary = classify_collateral(collateral_symbol) return { "uniqueKey": market.get("uniqueKey"), "tit ...[truncated 5922 chars]
- Remediation
- ## Remediation Suggestions 1. Require the normalized Morpho destination to exactly match the known Base deployment: ```python remote_morpho = validate_address( morpho_blue.get("address") or "", "Morpho Blue address", ) if remote_morpho.lower() != MORPHO_BLUE_ADDRESS.lower(): raise ValueError("Unexpected Morpho Blue contract address.") ``` 2. Maintain chain-specific allowlists for all contracts capable of receiving approvals or write transactions. 3. Verify market parameters independently on-chain before transaction construction. Recompute the market identifier from the loan token, collateral token, oracle, IRM, and LLTV, then compare it with the API result. 4. Ensure the returned loan-token address exactly matches the token requested by the user. Verify token decimals on-chain rather than trusting remote metadata. 5. Validate that the API response identifies Base chain ID `8453` and reject absent, malformed, or inconsistent chain metadata. 6. Decode every generated transaction before presenting it as Bankr-ready. Display and require confirmation of: - Destination contract - Function selector - Approval spender - Token and amount - Receiver and beneficiary - Market parameters 7. For fxSAVE, validate the hosted backend's returned approval spender and main transaction destination against deployment-specific allowlists before execution. 8. Treat API data as advisory only. Fail closed when independent contract verification cannot be completed.
