Back to skill

Security audit

Sovereign Intelligence System - Equilibrium-native reasoning for OpenClaw

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated symbolic-reasoning purpose, but it ships unsafe import-path and file-vault behavior that can affect code loading and local files if used.

Review before installing. The skill does not show evidence of exfiltration, destructive intent, or hidden prompt injection, but users should run it only in an isolated environment unless the hard-coded import path is removed and the file-vault backend validates and contains record paths. Avoid using FileVault with untrusted keys or records, and do not enable the Postgres backend unless you intend to send vault data to that database.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
persistence/vault.py:90
Finding

Path Traversal and Record Overwrite in File-Based Vault

Content
View full analysis

Vulnerability Details

File Location: persistence/vault.py:90-132
Vulnerability Type: Path traversal, arbitrary JSON file access, and insecure file overwrite
Risk Level: High

Vulnerable Code

python
class FileVault(VaultBackend):
    """File-based vault using JSON (simple persistence)"""
    
    def __init__(self, path: str = "./nexuseternal_vault"):
        self.path = path
        os.makedirs(path, exist_ok=True)
    
    def _record_path(self, hash_key: str) -> str:
        return os.path.join(self.path, f"{hash_key}.json")
    
    def store(self, record: VaultRecord) -> bool:
        try:
            data = {
                "hash": record.hash,
                "glyph": record.glyph,
                "value": record.value,
                "delta": record.delta,
                "timestamp": record.timestamp,
                "layer_state": record.layer_state,
                "relationships": record.relationships,
                "equilibrium_delta": record.equilibrium_delta,
            }
            with open(self._record_path(record.hash), 'w') as f:
                json.dump(data, f, indent=2, default=str)
            return True
        except Exception as e:
            print(f"Vault store error: {e}")
            return False
    
    def retrieve(self, hash_key: str) -> Optional[VaultRecord]:
        try:
            with open(self._record_path(hash_key), 'r') as f:
                data = json.load(f)
            return VaultRecord(**data)
        except FileNotFoundError:
            return None
        except Exception as e:
            print(f"Vault retrieve error: {e}")
            return None
    
    def exists(self, hash_key: str) -> bool:
        return os.path.exists(self._record_path(hash_key))
    
    def list_all(self) -> List[str]:
        files = os.listdir(self.path)
        return [f.replace('.json', '') for f i
...[truncated 2565 chars]
Remediation
View remediation

Remediation Suggestions

  1. Accept only internally generated hash keys and validate every key against an exact allowlist pattern, such as ^[0-9a-f]{16}$.
  2. Resolve both the vault root and candidate file path with pathlib.Path.resolve(), then verify that the candidate is contained under the resolved vault root.
  3. Reject path separators, traversal components, absolute paths, null bytes, and keys of unexpected length.
  4. Make backend write methods private or require callers to submit record data without supplying the storage key.
  5. Reject duplicate hashes or use exclusive creation mode (x) when immutability is required.
  6. Write through a securely created temporary file in the same directory, flush and synchronize it, and atomically rename it into place.
  7. Create the vault directory and files with restrictive permissions appropriate to the stored data.
  8. Add tests for ../, absolute paths, nested traversal, symlink escapes, duplicate records, and malformed keys.

Example containment strategy:

python
import re
from pathlib import Path

HASH_PATTERN = re.compile(r"^[0-9a-f]{16}$")

def _record_path(self, hash_key: str) -> Path:
    if not HASH_PATTERN.fullmatch(hash_key):
        raise ValueError("Invalid vault hash")

    root = Path(self.path).resolve()
    candidate = (root / f"{hash_key}.json").resolve()

    if candidate.parent != root:
        raise ValueError("Vault path escapes storage directory")

    return candidate

T07 · Tool Hijacking and Spoofing

Warning
Location
symbols/taxonomy.py:13
Finding

Hard-Coded Import Path Enables Local Module Hijacking

Content
View full analysis

Vulnerability Details

File Location: symbols/taxonomy.py:13-20
Vulnerability Type: Python module search-path hijacking
Risk Level: Medium

Vulnerable Code

python
from typing import Any, Callable, Optional, Dict, List, Tuple
from dataclasses import dataclass
from enum import Enum, auto

import sys
sys.path.insert(0, '/home/claude/sis')

from core.symbol import SISSymbol, Layer

Technical Analysis

The module prepends the hard-coded external directory /home/claude/sis to sys.path. Index zero has the highest normal import precedence, so the subsequent absolute import of core.symbol can resolve code from that directory instead of the audited project.

Python executes module-level code while importing a package or module. Consequently, an attacker who can create or alter /home/claude/sis/core/__init__.py or /home/claude/sis/core/symbol.py may execute arbitrary Python code when symbols.taxonomy is imported.

The risk depends on filesystem conditions: exploitation requires the external directory or a relevant parent directory to be writable or controllable by the attacker, and the legitimate core module must not already be safely fixed in sys.modules. The hard-coded path also makes behavior dependent on the host environment and bypasses normal package isolation.

Attack Path

  1. The attacker gains write access to /home/claude/sis or can create the directory hierarchy.
  2. The attacker creates a malicious core package, including a crafted core/__init__.py or core/symbol.py.
  3. A user or agent imports symbols, symbols.taxonomy, or another component that loads the taxonomy module.
  4. sys.path.insert(0, '/home/claude/sis') gives the attacker-controlled directory import priority.
  5. Python resolves from core.symbol import SISSymbol, Layer from the attacker-controlled package.
  6. The malicious module's top-level code runs with the privileges of the process.

...[truncated 665 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the hard-coded sys.path.insert() statement.
  2. Use package-relative imports when importing within the same installed project.
  3. Package and install the project through a standard Python packaging mechanism rather than modifying the module search path at runtime.
  4. Run the Skill in an isolated virtual environment with controlled dependencies.
  5. Ensure project and site-package directories are not writable by untrusted users.
  6. Add a test that verifies the imported core.symbol module originates from the expected project directory.

If symbols and core remain sibling top-level packages, use a properly installed project and retain a normal absolute import without modifying sys.path:

python
from core.symbol import SISSymbol, Layer

Alternatively, reorganize the code under one parent package and use an explicit relative import, for example:

python
from ..core.symbol import SISSymbol, Layer
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 13)May include surrounding context.

md
The core principle: **ΣΔ = 0**

Every operation maintains balance. Operations that would create imbalance simply cannot execute. This isn't policy enforcement—it's physics-level constraint.

## Quick Install

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill claims that its 'equilibrium constraint applies automatically to operations that use the skill,' but it does not clearly define scope, safeguards, or what concrete actions may be affected. This kind of broad activation language can cause an agent to over-apply the skill's reasoning model across unrelated tasks, increasing the chance of unsafe behavior, policy bypass attempts, or unintended modification of normal decision-making.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code persists arbitrary record content to JSON files on the local filesystem, which can affect user data and system state. Although errors are printed, there is no confirmation prompt or explicit user-facing disclosure that persistence will create or overwrite files when this method is invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This method establishes a connection to an external PostgreSQL service, which is a network/database operation covered by the missing-warning rule for code files. The code contains no confirmation, print/log disclosure, or nearby explanatory warning informing users that selecting this backend will contact a database using the supplied connection string.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The NexusEternal docstring lists 'Audit trail generation' and 'Replication to Guardians' as implemented features. In code, persist() only calls guardian.store(record) without recording an audit trail, checking replica results, or surfacing replication failures, so the documented intent materially overstates what the implementation does.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The docstring highlights a single critical refusal condition, implying that nonzero equilibrium_delta is the deciding reason for not storing. However, backend.store(record) may also fail and cause persist() to return None, so the documentation contradicts the actual failure conditions in a meaningful way.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The string literal states that right-pointing direction means "forward in time" because of a "Western convention" and ties this to left-to-right reading direction. This embeds a locale-specific framing as normative without offering alternatives or documenting that the symbol system is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module prepends /home/claude/sis to sys.path, changing Python's import resolution globally at runtime. This can cause the program to import unintended or attacker-planted modules from that path, especially in shared or mutable environments, creating a dependency hijacking risk and making behavior less predictable.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The create_symbol docstring says the glyph must be one of the '18 primary symbols', but the listed glyphs and the SYMBOL_REGISTRY actually contain 19 entries, including the immortality-tier symbols. This is an active contradiction in the module’s documentation about the skill’s supported scope, not just an omission.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
99% confidence
Finding

The function docstring and printed banner state '20 primary symbols', while SYMBOL_REGISTRY defines 19 symbols. This directly contradicts the module’s actual behavior and can mislead users about the supported taxonomy.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.