Back to skill

Security audit

Agent Audit Trail

Security checks for vulnerabilities and agentic risk

Overview

This audit-log skill is not malicious, but it needs review because it creates durable records of sensitive activity while its sample integrity logic has reliability flaws.

Install only if you are comfortable maintaining a persistent local audit log of agent activity. Before using it for compliance or incident evidence, fix the hash-chain genesis mismatch, add locking or a single-writer design, restrict file permissions, define retention, and redact credential names, session identifiers, wallet addresses, transaction metadata, and other sensitive fields where possible. Verify any companion skills before installing them.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:315
Finding

Unverified Third-Party Skill Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 315-348
Vulnerability Type: Unpinned and unverified third-party dependencies
Risk Level: Medium

Complete Code Snippet

markdown
### `agent-self-assessment` (v2.2.1)
> Run the assessment first, then set up logging for ongoing compliance.

The self-assessment skill provides a 14-check compliance and security framework with RED/AMBER/GREEN ratings. Use it to determine your EU AI Act risk classification before configuring this audit trail.

**Install:**
```bash
clawhub install agent-self-assessment

Or if already available in your workspace:

text
Read ~/.openclaw/workspace/skills/agent-self-assessment/SKILL.md

Workflow:

  1. Run agent-self-assessment → identify gaps + risk tier
  2. Install agent-audit-trail → implement logging for ongoing compliance
  3. Schedule periodic re-assessments (monthly/quarterly)

agirails (v3.0.0)

Enable payment tracking in your audit trail.

AGIRAILS provides ACTP escrow and x402 instant payment primitives for AI agents. All payments should be logged using the payment kind in this audit trail.

Install:

bash
clawhub install agirails

Or if already available in your workspace:

text
Read ~/.openclaw/workspace/skills/agirails/SKILL.md
text

### Technical Analysis

The skill recommends installing two external skills by mutable package names. Although versions are mentioned in headings and project metadata, the installation commands do not pin those versions or verify a cryptographic digest, publisher signature, or trusted source repository.

Consequently, the content installed at execution time may differ from the content implied by the audited documentation. This creates a supply-chain trust gap: registry compromise, package ownership transfer, dependency substitution, or a malicious later release could cause the user to install unreviewed instructions or
...[truncated 1166 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin each companion skill to an immutable, explicitly supported version in the installation command.
  • Require verification against a publisher signature or documented cryptographic digest.
  • Identify the authoritative registry and source repository.
  • Download and inspect package contents before activation.
  • Require explicit human approval after presenting the resolved version, publisher, permissions, and integrity information.
  • Maintain an allowlist of approved package identities and hashes.
  • Isolate third-party skills with least-privilege filesystem, network, credential, and tool permissions.
  • Document a rollback and revocation process for compromised companion packages.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:154
Finding

Inconsistent Genesis Hash Makes Generated Logs Fail Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 154-159 and 202-215
Vulnerability Type: Inconsistent hash-chain initialization
Risk Level: Medium

Complete Code Snippet

Writer:

python
def last_hash():
    lines = LOG.read_text().strip().splitlines() if LOG.exists() else []
    if not lines:
        return "sha256:0" * 1  # genesis
    last = json.loads(lines[-1])
    return last.get("hash", "sha256:genesis")

Verifier:

python
LOG = Path("audit/atlas-actions.ndjson")
lines = LOG.read_text().strip().splitlines()
prev = "sha256:genesis"

for i, line in enumerate(lines):
    entry = json.loads(line)
    stored_hash = entry.pop("hash")
    raw = json.dumps(entry, separators=(",", ":"))
    computed = "sha256:" + hashlib.sha256(raw.encode()).hexdigest()
    if stored_hash != computed:
        print(f"CHAIN BROKEN at entry {i} (ord={entry.get('ord')})")
        break
    if entry.get("prev_hash") != prev:
        print(f"PREV_HASH MISMATCH at entry {i}")
        break

Technical Analysis

The writer assigns the first log entry a prev_hash value of sha256:0, while the verifier initializes the expected previous hash to sha256:genesis. These are different values. Therefore, an otherwise valid first entry produced by the documented helper deterministically fails verification with PREV_HASH MISMATCH.

The expression "sha256:0" * 1 does not generate a zero-filled SHA-256 digest; it simply returns the literal string sha256:0. The fallback used when an existing last entry lacks a hash introduces a third semantic path by returning sha256:genesis, further weakening the consistency of the chain protocol.

This is not a cryptographic break of SHA-256. It is an implementation error that prevents the integrity mechanism from reliably distinguishing valid records from corrupted records.

Attack Path

  1. An operator creates an empty audit log.
  2. T ...[truncated 844 chars]
Remediation
View remediation

Remediation Suggestions

  • Define one canonical genesis constant, such as:
    python
    GENESIS_HASH = "sha256:" + ("0" * 64)
    
  • Import or reuse that same constant in both writer and verifier.
  • Reject an existing last entry that lacks a valid hash instead of silently substituting another genesis value.
  • Validate that hash and prev_hash match ^sha256:[0-9a-f]{64}$.
  • Add automated tests for empty logs, one-entry logs, multi-entry logs, malformed entries, modified entries, and deleted or reordered entries.
  • Include a versioned canonical serialization specification so independent implementations calculate identical hashes.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:154
Finding

Concurrent Appends Can Fork the Hash Chain and Duplicate Sequence Numbers

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 154-186
Vulnerability Type: Race condition in append-only audit logging
Risk Level: High

Complete Code Snippet

python
def last_hash():
    lines = LOG.read_text().strip().splitlines() if LOG.exists() else []
    if not lines:
        return "sha256:0" * 1  # genesis
    last = json.loads(lines[-1])
    return last.get("hash", "sha256:genesis")

def last_ord():
    lines = LOG.read_text().strip().splitlines() if LOG.exists() else []
    if not lines:
        return 0
    return json.loads(lines[-1]).get("ord", 0)

def append(kind, actor, domain, plane, gate, provenance, target, summary):
    entry = {
        "ts":         datetime.now(TZ).isoformat(),
        "kind":       kind,
        "actor":      actor,
        "domain":     domain,
        "plane":      plane,
        "gate":       gate,
        "ord":        last_ord() + 1,
        "provenance": provenance,
        "target":     target,
        "summary":    summary,
        "prev_hash":  last_hash(),
    }
    raw    = json.dumps({k: v for k, v in entry.items()}, separators=(",", ":"))
    digest = "sha256:" + hashlib.sha256(raw.encode()).hexdigest()
    entry["hash"] = digest
    with LOG.open("a") as f:
        f.write(json.dumps(entry) + "\n")
    return entry

Technical Analysis

Sequence allocation, previous-hash retrieval, and append are separate operations with no lock or transactional boundary. Two processes can call append simultaneously, read the same last sequence number and hash, and then independently create successor records.

Both records can receive the same ord and prev_hash. After both are appended, only the first is the linear successor of the prior record; the second forms a competing branch and does not reference the immediately preceding physical line. The verifier will reject the resulting file.

The implementa ...[truncated 1409 chars]

Remediation
View remediation

Remediation Suggestions

  • Enforce a single-writer architecture or acquire an operating-system-level exclusive lock before reading the last record.
  • Hold the lock across sequence allocation, previous-hash selection, serialization, hashing, append, flush, and fsync.
  • Read the final record once while locked rather than scanning the entire file twice.
  • Use a transactional datastore when logging from multiple hosts or containers, because local file locks do not coordinate distributed writers.
  • Create the log with restrictive permissions and prevent untrusted processes from writing directly.
  • Check that the current final hash has not changed immediately before commit.
  • Add concurrency tests with multiple processes and verify strict uniqueness of ord and a single linear hash chain.
  • Define recovery behavior for partial writes, malformed final lines, process termination, and disk-full conditions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 237)May include surrounding context.

plane="action", gate="external-write", provenance="session:agent:main:discord:...", target="https://api.agirails.xyz/v1/escrow", summary="Created ACTP escrow 0xabc... for 10 USDC" )

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly encourages logging sensitive events such as credential access and external writes, including examples that place a secret identifier in the target field and operational details in summary. While intended for compliance and traceability, this creates a realistic risk of storing secret names, system topology, transaction metadata, or other sensitive operational data in a durable audit log without any minimization, masking, retention, or access-control guidance.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 326)May include surrounding context.

Or if already available in your workspace:

text
Read ~/.openclaw/workspace/skills/agent-self-assessment/SKILL.md

Workflow:

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 348)May include surrounding context.

Or if already available in your workspace:

text
Read ~/.openclaw/workspace/skills/agirails/SKILL.md

Payment logging integration:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The field reference specifies timestamps with a Europe/London timezone offset, and setup examples repeat that requirement as a fixed convention. This is a locale constraint presented as mandatory behavior without user opt-in or a documented justification that the skill is region-specific in its timestamp policy.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.