T09 · Insecure Skill Coding Practices
- Location
scripts/orchestrator.py:154- Finding
Workflow Conditions Fail Open and Permit Guarded Steps to Execute
- Content
View full analysis
bool: """Evaluate a simple condition like '$.step.status == "completed"'.""" if not condition: return True # Simple evaluator — production would use JSONPath try: if "==" in condition: path, expected = condition.split("==", 1) path = path.strip().lstrip("$.").split(".") value = context for key in path: value = value.get(key, {}) if isinstance(value, dict) else {} return str(value).strip() == expected.strip().strip('"') except Exception: pass return True ``` ### Technical Analysis The condition evaluator defaults to `True` whenever a condition cannot be evaluated. This includes: - Conditions using unsupported operators or syntax. - Conditions without the `==` operator. - Conditions that trigger an exception. - Unexpected condition types or malformed path expressions. This is a fail-open design. A workflow condition commonly acts as a security or safety gate that controls whether a consequential agent action may run. When parsing or evaluation fails, execution should be denied or the workflow should be rejected. Instead, the current implementation treats invalid conditions as satisfied. The behavior also differs from the documented JSONPath condition support. The implementation only recognizes a limited equality expression and silently permits execution for unsupported expressions. ### Attack Path 1. An attacker or untrusted workflow author defines a step that performs a consequential action, such as publishing data, sending a notification, deploying an artifact, or deleting a resource. 2. The attacker supplies a malformed or unsupported co ...[truncated 823 chars]- Remediation
View remediation
bool: if not condition: return True if not isinstance(condition, str) or "==" not in condition: raise ValueError("Unsupported workflow condition") path, expected = condition.split("==", 1) keys = path.strip().removeprefix("$.").split(".") value = context for key in keys: if not isinstance(value, dict) or key not in value: return False value = value[key] return str(value).strip() == expected.strip().strip('"') ``` ]]>
