T09 · Insecure Skill Coding Practices
- Location
warden_governance/sentinel_client.py:34- Finding
Governance decisions can be bypassed through an under-scoped authorization cache
- Content
View full analysis
CheckResult | None: key = f"{action_type}:{env}" entry = self._cache.get(key) if entry is None: self._misses += 1 return None if time.time() - entry["cached_at"] > self._ttl: del self._cache[key] self._misses += 1 return None self._hits += 1 return entry["result"] def set(self, action_type: str, env: str, result: CheckResult) -> None: if result.decision != Decision.ALLOW: return key = f"{action_type}:{env}" self._cache[key] = {"result": result, "cached_at": time.time()} ``` The cached result is returned before policy evaluation: ```python env = action.context.get("env", "dev") cached = self.cache.get(action.type.value, env) if cached is not None: return cached ``` The affected policies distinguish operations using fields that are absent from the cache key: ```yaml - name: protect-email-delete match: action.type: data.write action.data.openclaw_original: email.delete decision: review - name: protect-file-delete match: action.type: data.write action.data.openclaw_original: file.delete decision: review - name: review-payments match: action.type: api.call action.data.openclaw_original: payment.create decision: review ``` ### Technical Analysis The cache key contains only the normalized action type and environment. However, policy evaluation also depends on the original OpenClaw action, action data, service, data classification, agent identity, and arbitrary context fields. Several different operations are normalized to the same governance type. For example, `file.write`, `email.delete`, `fi ...[truncated 1475 chars]- Remediation
View remediation
