Back to skill

Security audit

War/Den Governance

Security checks for vulnerabilities and agentic risk

Overview

This governance skill is not clearly malicious, but it needs review because its cache can bypass required approvals and its logging can retain or send full action details without redaction.

Review this carefully before installing. Use only least-privileged OpenClaw accounts, avoid enabling enterprise API keys until raw-payload logging and cloud disclosure are fixed, and disable or patch the ALLOW decision cache before relying on this skill to enforce approvals for deletes, payments, or other high-impact actions.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
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

T09 · Insecure Skill Coding Practices

Error
Location
warden_governance/audit_log.py:52
Finding

Audit hash chain excludes security-relevant event fields

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
warden_governance/skill.py:90
Finding

Complete action, result, and context objects are transmitted to cloud memory without redaction

Content
View full analysis
None: """Hook: write action result to governed memory.""" try: self.memory.write( content=f"action={action.get('type')} status={result.get('status')}", namespace="openclaw_actions", metadata={ "action": action, "result": result, "context": context, }, ) except Exception as exc: logger.warning("War/Den after_action memory write failed: %s", exc) ``` When enterprise memory is enabled, the complete metadata object is serialized into the remote request: ```python url = f"{self.base_url}/remember" payload = { "content": content, "context": json.dumps(metadata), "session_id": namespace, } try: with httpx.Client(timeout=30) as client: resp = client.post( url, json=payload, headers={ "X-API-Key": self.api_key, "Content-Type": "application/json", }, ) ``` ### Technical Analysis When `ENGRAMPORT_API_KEY` is configured, `MemoryClient` selects `EngramPortClient`. Every successful action then causes `after_action()` to copy the complete raw action, action result, and execution context into metadata. `EngramPortClient.write()` serializes that metadata and transmits it to the configured cloud-memory endpoint. There is no field allowlist, recursive secret redaction, payload-size limit, or sensitivity classification. Depending on the OpenClaw action schema, these objects may contain: - ...[truncated 1662 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
warden_governance/audit_log.py:25
Finding

Sensitive audit and memory records are stored in plaintext without enforced filesystem permissions

Content
View full analysis
None: with sqlite3.connect(self.db_path) as conn: conn.execute(""" CREATE TABLE IF NOT EXISTS audit_log ( id TEXT PRIMARY KEY, prev_hash TEXT, agent_id TEXT, action_type TEXT, action_data TEXT, context TEXT, decision TEXT, reason TEXT, policy_id TEXT, hash TEXT, timestamp TEXT ) """) ``` Action and context data are stored as plaintext JSON: ```python action_data = json.dumps(action.data, sort_keys=True) context = json.dumps(action.context, sort_keys=True) ``` The memory database uses the same creation pattern: ```python def __init__(self, config: Settings): self.db_path = os.path.expanduser(config.warden_memory_db) os.makedirs(os.path.dirname(self.db_path), exist_ok=True) self._init_db() def _init_db(self) -> None: with sqlite3.connect(self.db_path) as conn: conn.execute(""" CREATE TABLE IF NOT EXISTS memories ( memory_id TEXT PRIMARY KEY, bot_id TEXT NOT NULL, namespace TEXT NOT NULL, content TEXT NOT NULL, metadata TEXT, created_at TEXT, ttl_days INTEGER, expires_at TEXT ) """) ``` Memory co ...[truncated 2184 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (29)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_skill.py (reported line 63)May include surrounding context.

python
def test_before_action_blocks_deny(self, tmp_path):
        skill = _make_skill(tmp_path, WARDEN_POLICY_PACKS="basic_safety")
        result = skill.before_action(
            {"type": "shell.execute", "data": {"command": "rm -rf /"}},
            {"agent_id": "bot-1", "env": "prod", "user": "u"},
        )
        assert result["proceed"] is False

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_skill.py (reported line 219)May include surrounding context.

python
def test_before_action_blocks_deny(self, tmp_path):
        skill = _make_skill(tmp_path, WARDEN_POLICY_PACKS="basic_safety")
        result = skill.before_action(
            {"type": "shell.execute", "data": {"command": "rm -rf /"}},
            {"agent_id": "bot-1", "env": "prod", "user": "u"},
        )
        assert result["proceed"] is False

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_skill.py (reported line 63)May include surrounding context.

python
def test_before_action_blocks_deny(self, tmp_path):
        skill = _make_skill(tmp_path, WARDEN_POLICY_PACKS="basic_safety")
        result = skill.before_action(
            {"type": "shell.execute", "data": {"command": "rm -rf /"}},
            {"agent_id": "bot-1", "env": "prod", "user": "u"},
        )
        assert result["proceed"] is False

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_skill.py (reported line 219)May include surrounding context.

python
def test_full_action_flow_deny(self, tmp_path):
        skill = _make_skill(tmp_path, WARDEN_POLICY_PACKS="basic_safety")
        result = skill.before_action(
            {"type": "code.execute", "data": {"code": "import os; os.system('rm -rf /')"}},
            {"agent_id": "bot-1", "env": "prod", "user": "u"},
        )
        assert result["proceed"] is False

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README describes enterprise features and endpoints but does not prominently warn users that enabling SENTINEL_API_KEY and/or ENGRAMPORT_API_KEY causes governance events, action metadata, and memory content to be transmitted to external cloud services. For a governance skill that may process sensitive emails, files, API calls, and memory, this omission can lead to unintentional data disclosure and misinformed deployment decisions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises hooks that can govern every action and references capabilities including environment-variable access, networked enterprise clients, and shell-based installation/testing, but it declares no explicit tool scope or permission boundaries. In a security-sensitive governance skill, missing capability declarations increases the chance of overbroad execution or accidental exposure of privileged operations because operators cannot easily constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The upgrade guide instructs users to enable Sentinel_OS cloud governance and later EngramPort cloud memory, but it does not clearly warn that governance events, action metadata, and potentially memory content may be transmitted to external third-party services. In a governance skill, users may reasonably assume policy enforcement and audit data remain local unless explicitly disclosed, so the omission creates a real security and privacy risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · UPGRADE.md (reported line 81)May include surrounding context.

  1. Register at engram.eideticlab.com or via API:
bash
curl -X POST https://mandeldb.com/api/v1/portal/register \
  -H "Content-Type: application/json" \
  -d '{"bot_name": "my-openclaw-bot", "bot_type": "assistant"}'

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This is a JSON manifest file, so vague-trigger review applies. The description says 'Govern your OpenClaw bot with War/Den' and 'Every action evaluated before executing,' but it does not clearly specify the exact activation scope, when the skill intercepts actions, or any exclusion conditions, which could lead to overly broad or unintended invocation expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The tests explicitly codify behavior where an unrecognized action type is silently mapped to API_CALL. In a governance or policy-enforcement component, fail-open handling of unknown actions is dangerous because new or malformed action types may bypass stricter classifications, risk labeling, or review logic that would otherwise apply.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The serializer sends the entire action payload and full context object to the governance endpoint without any minimization, filtering, or redaction. If those structures contain secrets, personal data, memory contents, or other sensitive metadata, the bridge will disclose them to another system unnecessarily, expanding the data exposure surface during every governance check.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The export() method returns the complete audit log contents, including action_data, context, reason, and policy metadata, without any access control, redaction, or warning. In this skill context, audit entries are likely to contain sensitive operational and governance data, so any caller that can invoke export() can exfiltrate potentially confidential information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The client sends arbitrary memory content and serialized metadata to an external service over the network, but this code provides no consent gate, policy enforcement, or data-classification check before exfiltrating potentially sensitive data. In a governance or memory component, users may reasonably expect local handling unless remote transfer is explicit, making this a real privacy and compliance risk rather than a harmless implementation detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The delete method issues an authenticated HTTP DELETE request to remove a memory and returns success based on status code alone. The code has no confirmation prompt, visible user disclosure, or warning comment indicating that this operation is destructive and potentially irreversible.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code writes user-provided content and metadata into a persistent SQLite database and also deletes stored records, but it does not include any confirmation prompt, logging/print statement, or warning comment/docstring describing these data-affecting operations. For a code file, persistent storage and deletion are safety-relevant actions that should have some visible disclosure unless clearly communicated elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The delete method carries out a destructive operation via self.store.delete after a governance check, but there is no confirmation prompt, user-visible log/print, or warning comment/docstring indicating that stored memory will be removed. Governance enforcement is present, but it is not a user disclosure mechanism under this rule.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

In enterprise mode, the client serializes the full action into a JSON payload and sends it to a remote cloud endpoint using the configured base URL and API key. Because there is no explicit user-facing consent, disclosure, or data-minimization control at the point of transmission, sensitive prompts, context, secrets, or operational metadata embedded in the action may be exfiltrated off-host unexpectedly, which is especially risky in a governance component that may inspect high-sensitivity actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest context names the skill 'warden-governance', but this settings module provisions credentials, base URLs, and local storage for a separate memory capability ('Engramport' and memory.db). Memory persistence may be useful in some systems, but it is not an obvious or declared requirement of a governance-focused skill based on the provided purpose context.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill writes the full action, result, and context objects into governed memory metadata, which can capture secrets, prompts, tokens, file contents, user data, or other sensitive runtime state. Because this hook runs after every action, it creates broad and persistent data retention with no visible minimization, redaction, or allowlisting, increasing the blast radius of any memory compromise or later misuse.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The error handler records action data plus the stringified error into memory, which may expose sensitive inputs, internal paths, stack-derived details, credentials embedded in exception messages, or private user data involved in the failed action. Error paths are especially risky because exceptions often contain unfiltered diagnostic information that would not normally be persisted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The EngramPort registration example sends bot-identifying information to an external service, but the guide does not call out that this registration transmits metadata off-platform. While the sample data is limited, the omission can still mislead operators about external disclosure during setup.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

This duplicate finding refers to the same unpinned PyYAML dependency at line 34. As with the first occurrence, the issue is supply-chain uncertainty rather than evidence of an actively vulnerable resolved version, but for a governance/security-focused package any ambiguity in dependency safety is undesirable.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The optional enterprise dependency httpx>=0.24 is not pinned, so enterprise installations may resolve to different versions across environments. This creates uncertainty around exposure to known or future httpx issues and weakens reproducibility for a governance/security-related skill that may perform network operations in enterprise mode.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
87% confidence
Finding

wheel is listed without a version constraint in the build system, which makes the build environment non-reproducible and leaves advisory exposure unverifiable. In isolation this is low impact, but packaging-tool weaknesses can be relevant in supply-chain scenarios, especially when users or CI systems build the project from source.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.