T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/kelly_calculator.py:124
- Finding
- Missing Numeric Input Validation Causes Denial of Service and Unsafe Position Recommendations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/kelly_calculator.py`, lines 16–35, 71–84, 124–140, 166–167, and 181–193 **Vulnerability Type**: Improper input validation and unsafe arithmetic **Risk Level**: Medium ### Vulnerable Code ```python def kelly_position(p: float, b: float, fraction: float = 0.5) -> float: """ Calculate Kelly position size. Args: p: Win probability (0-1) b: Win/Loss ratio (e.g., 2.0 means win 2x of what you lose) fraction: Kelly fraction (0.5 = half-Kelly, 0.25 = quarter-Kelly) Returns: Position size as percentage (0-1) """ if p <= 0.5 or b <= 0: return 0.0 f_star = (p * b - (1 - p)) / b if f_star < 0: return 0.0 return f_star * fraction ``` ```python def leverage_safety(liquidation_pct: float, stop_loss_pct: float) -> Tuple[bool, float]: """ Check if leverage is safe. Args: liquidation_pct: Distance to liquidation (e.g., 10 for 10%) stop_loss_pct: Stop loss distance (e.g., 3 for 3%) Returns: (is_safe, safety_factor) """ safety_factor = liquidation_pct / stop_loss_pct is_safe = safety_factor >= 2.0 return is_safe, safety_factor ``` ```python def calculate_trade(p: float, win_pct: float, loss_pct: float, fraction: float = 0.5, leverage: float = 1.0, liquidation_pct: Optional[float] = None, stop_loss_pct: Optional[float] = None) -> dict: """ Full trade calculation with all factors. """ b = win_pct / loss_pct # Basic Kelly full_kelly = kelly_position(p, b, 1.0) half_kelly = kelly_position(p, b, 0.5) quarter_kelly = kelly_position(p, b, 0.25) # Net edge method edge = net_edge(p, win_pct, loss_pct) suggested = suggested_position(edge, win_pct, fraction) ``` ```python # Leverage check if leverage > 1 and liquidation_pct and stop_loss_pct ...[truncated 4393 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Add centralized validation before performing any calculation: ```python import math def validate_inputs( p: float, win_pct: float, loss_pct: float, fraction: float, leverage: float, liquidation_pct: Optional[float], stop_loss_pct: Optional[float], ) -> None: values = { "probability": p, "win percentage": win_pct, "loss percentage": loss_pct, "fraction": fraction, "leverage": leverage, } for name, value in values.items(): if not math.isfinite(value): raise ValueError(f"{name} must be finite") if not 0 <= p <= 1: raise ValueError("probability must be between 0 and 1") if win_pct <= 0: raise ValueError("win percentage must be greater than zero") if loss_pct <= 0: raise ValueError("loss percentage must be greater than zero") if not 0 < fraction <= 1: raise ValueError("Kelly fraction must be greater than 0 and at most 1") if leverage < 1: raise ValueError("leverage must be at least 1") for name, value in ( ("liquidation distance", liquidation_pct), ("stop-loss distance", stop_loss_pct), ): if value is not None: if not math.isfinite(value) or value <= 0: raise ValueError(f"{name} must be finite and greater than zero") ``` 2. Invoke validation at the start of `calculate_trade()` before calculating the win/loss ratio. 3. Replace the leverage truthiness check with explicit presence checks: ```python if leverage > 1: if liquidation_pct is None or stop_loss_pct is None: raise ValueError( "liquidation and stop-loss distances are required when leverage is greater than 1" ) is_safe, safety_factor = leverage_safety( liquidation_pct, st ...[truncated 635 chars]
