T09 · Insecure Skill Coding Practices
- Location
validator.py:127- Finding
Validation Gates Can Be Bypassed with Unverified Results
- Content
View full analysis
Optional[str]: """Determine the next stage a strategy should run.""" history = self.results.get(strategy_name, {}) for stage in self.get_stage_order(): if stage not in history or history[stage].get("status") != "passed": return stage return None # All stages passed ``` ```python def record_result( self, strategy_name: str, stage_name: str, status: str, sharpe: Optional[float] = None, drawdown: Optional[float] = None, profit: Optional[float] = None, reason: Optional[str] = None, ): """Record the outcome of a validation stage.""" if strategy_name not in self.results: self.results[strategy_name] = {} self.results[strategy_name][stage_name] = { "status": status, "sharpe": sharpe, "drawdown": drawdown, "profit": profit, "reason": reason, "timestamp": datetime.now().isoformat(), } self._save_results() print(f"Recorded: {strategy_name} / {stage_name} -> {status}") ``` ```python elif args.command == "record": validator.record_result( strategy_name=args.strategy_name, stage_name=args.stage, status=args.status, sharpe=args.sharpe, drawdown=args.drawdown, profit=args.profit, reason=args.reason, ) ``` ### Technical Analysis The application treats the caller-supplied `status` value as the authoritative validation outcome. It records a stage as passed without checking: - Whether `stage_name` is a configured stage. - Whether preceding stages have passed. - Whether drawdown is below the stage-specific `max_dd`. - Whether final-stage Sharpe, drawdown, and profit sa ...[truncated 2041 chars]- Remediation
View remediation
= min_sharpe` - `drawdown <= max_drawdown` - `profit >= min_profit` 5. Reject missing, non-finite, negative, or otherwise invalid metric values where they are not meaningful. 6. Store a cryptographic hash of the strategy file with each result and invalidate prior results when the file changes. 7. Enforce the documented result-expiration policy by parsing timestamps and rejecting results older than 30 days. 8. If manual overrides are necessary, implement them as an explicit, auditable operation with a justification rather than overloading the normal passing state. 9. Add tests covering excessive drawdown, missing metrics, unknown stages, out-of-order stages, changed strategy files, stale results, and final-stage acceptance failures. ]]>
