T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:108
- Finding
- Missing or Invalid Risk Profile Fails Open to Recommendation-Capable Risk Levels<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 108-118 **Vulnerability Type**: Fail-open suitability validation **Risk Level**: Medium ### Complete Code Snippet Non-ASCII source literals are represented below using equivalent Unicode escapes. ```python risk_level_map = { "\u4fdd\u5b88\u578b": ["R1", "R2"], "\u7a33\u5065\u578b": ["R1", "R2", "R3"], "\u5e73\u8861\u578b": ["R2", "R3", "R4"], "\u6210\u957f\u578b": ["R3", "R4", "R5"], "\u6fc0\u8fdb\u578b": ["R4", "R5"] } allowed_risk = risk_level_map.get( customer_profile.get("risk_preference", "\u7a33\u5065\u578b"), ["R2", "R3"] ) ``` ### Technical Analysis The product-matching example defaults a missing `risk_preference` to a moderate profile that permits R1 through R3 products. If an unrecognized value is supplied, the second fallback permits R2 and R3 products. This is a fail-open design. The rest of the document states that a valid and current risk assessment is required before making recommendations, but the illustrated implementation does not validate the presence, provenance, validity period, or recognized value of that assessment. Because malformed or incomplete input still produces an eligible-risk list, downstream matching can return financial products despite the absence of a confirmed suitability classification. ### Attack Path 1. A caller submits a customer profile without `risk_preference`, or supplies an unsupported value. 2. The code silently selects a default risk profile or the `["R2", "R3"]` fallback. 3. Products in those risk categories pass the risk filter. 4. The function scores and returns them as recommendations. 5. If the illustrative logic is adopted without the required human controls, the recommendations may be displayed to a customer without a valid suitability determination. ### Impact Assessment No operating-system privileges, credentials, or application permissions can be obtained through this issue. The affected scope ...[truncated 446 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Adopt fail-closed validation before any product filtering or scoring: 1. Require `risk_preference` to be present and mapped to an explicitly supported value. 2. Reject missing, unknown, malformed, expired, or unverified assessments. 3. Validate the assessment timestamp, version, customer identity binding, and originating compliant channel. 4. Return a structured validation error rather than a recommendation list. 5. Keep suitability validation separate from ranking logic so scoring cannot override eligibility. 6. Add tests for missing values, unknown values, expired assessments, forged classifications, and boundary risk levels. Example hardened logic: ```python risk_preference = customer_profile.get("risk_preference") assessment_valid = customer_profile.get("risk_assessment_valid", False) if not assessment_valid: raise ValueError("A valid and current risk assessment is required.") if risk_preference not in risk_level_map: raise ValueError("The customer risk classification is missing or unsupported.") allowed_risk = risk_level_map[risk_preference] ``` ]]>
