Back to skill

Security audit

OpenClaw Security PII Audit

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims: it scans supplied session content for PII and stores masked local audit records, with no evidence of hidden exfiltration or destructive behavior.

Install only if you are comfortable with a local Python worker receiving sensitive session, prompt, context, or knowledge-base text and writing masked audit records plus content hashes to disk. Use the documented file plus delete-after-read workflow, keep the audit directory access-restricted, run cleanup according to your retention needs, and avoid relying on the audit log as a perfect compliance trail under heavy concurrent scans until the file-lock weakness is fixed.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/file_lock.py:45
Finding

Active File Locks Can Be Forcibly Removed

Content
View full analysis

Vulnerability Details

File Location: scripts/file_lock.py, lines 45–61 and 64–72
Vulnerability Type: Unsafe stale-lock recovery and missing lock ownership validation
Risk Level: Medium

Vulnerable Code

python
except (FileExistsError, OSError):
    if time.monotonic() >= deadline:
        # Timeout — attempt stale-lock recovery once
        self._remove_stale()
        try:
            self._fd = os.open(
                self.lock_path,
                os.O_CREAT | os.O_EXCL | os.O_WRONLY,
            )
            return
        except (FileExistsError, OSError):
            raise FileLockTimeout(
                f'Could not acquire lock: {self.lock_path}'
            )
python
def release(self) -> None:
    if self._fd is not None:
        try:
            os.close(self._fd)
        except OSError:
            pass
        self._fd = None
    self._remove_stale()

def _remove_stale(self) -> None:
    try:
        os.remove(self.lock_path)
    except OSError:
        pass

Technical Analysis

The lock uses atomic exclusive file creation, but after the five-second timeout it assumes that any existing lock is stale and deletes it. The implementation does not inspect the lock's age, record the owning process, verify owner liveness, or associate the lock file with a unique ownership token.

Consequently, a waiting process can delete a lock that is still actively held. It can then create a replacement lock and enter the protected critical section while the original holder is still operating. The original holder's release() method also removes the lock path unconditionally, even if that path now represents a replacement lock owned by another process.

This defeats the mutual-exclusion guarantees relied upon by audit-log appends and scan-cache access.

Attack Path

  1. An audit worker acquires an audit-log or scan-cache lock.
  2. The worker remains in the protected section for longer than the configured five-second timeout, ...[truncated 1598 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add lock ownership identity

    • Generate a cryptographically random token when acquiring a lock.
    • Write the token, process ID, creation timestamp, and optionally host identity into the lock file.
    • Retain the token in the FileLock instance.
  2. Validate ownership during release

    • Before deleting the lock file, read and compare its token with the token held by the current instance.
    • Never remove a lock whose ownership token does not match.
    • Where possible, perform ownership verification and deletion atomically.
  3. Use safe stale-lock recovery

    • Do not classify a lock as stale solely because a waiter reached its timeout.
    • Require the lock's recorded age to exceed a separately configured stale-lock threshold.
    • Where supported, verify that the owning process is no longer alive.
    • If owner liveness cannot be established safely, fail with FileLockTimeout rather than deleting the lock.
  4. Prefer native locking mechanisms

    • Use POSIX fcntl.flock on Unix-like systems and an appropriate Windows locking primitive such as msvcrt.locking.
    • Alternatively, use a maintained cross-platform file-locking library with ownership-safe stale-lock handling.
  5. Harden cache updates

    • Keep cache loading, modification, and saving inside one continuous lock scope.
    • Write updated cache data to a temporary file in the same directory, flush and synchronize it, and atomically replace the destination.
  6. Add concurrency tests

    • Verify that a waiter cannot remove a live lock after timing out.
    • Verify that an old owner cannot delete a replacement lock.
    • Stress-test concurrent audit appends and cache updates with operations exceeding the timeout.
    • Confirm that timeout failures preserve the active owner's lock and protected data.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill marketed for PII scanning but apparently implementing only file locking/concurrency behavior represents a severe trust and control failure. Because the skill context is security auditing, any absence of real detection logic is more dangerous than in a generic utility: operators may depend on it to protect sensitive session content while it performs unrelated local file operations instead.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest claims the skill scans user input, prompts, context, and knowledge base content for personal data across regions. In this file, the implemented behavior is exclusively filesystem cleanup of an 'openclaw-security-audit' directory and pruning of '.scan-cache.json', which does not perform any detection or scanning.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a multi-region async PII detection skill that scans session-related content for sensitive data. This script instead performs retention cleanup by deleting dated audit directories and rewriting the scan cache, which is an operational log-maintenance capability rather than PII detection itself.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation instructs use of shell execution, environment variables, and file read/write operations, but it does not declare any corresponding tool scope or permissions. This creates a capability mismatch that can cause over-privileged execution or bypass review controls, especially because the skill handles sensitive session content and writes audit artifacts to disk.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · tests/test_all.py (reported line 738)May include surrounding context.

python
with open(self.lock_path, 'w') as f:
            f.write('stale')
        # Should recover (via timeout + stale removal)
        lock = FileLock(self.lock_path, timeout=0.2, poll_interval=0.05)
        lock.acquire()
        lock.release()

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · tests/test_all.py (reported line 746)May include surrounding context.

python
with open(self.lock_path, 'w') as f:
            f.write('stale')
        # Should recover (via timeout + stale removal)
        lock = FileLock(self.lock_path, timeout=0.2, poll_interval=0.05)
        lock.acquire()
        lock.release()

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · tests/test_all.py (reported line 989)May include surrounding context.

python
# The cutoff should use UTC
        now_utc = datetime.now(timezone.utc)
        # A directory from 8 days ago should be cleaned with 7-day retention
        eight_ago = (now_utc - __import__('datetime').timedelta(days=8))
        old_name = eight_ago.strftime('%Y-%m-%d')
        old_dir = Path(self.tmpdir) / old_name
        old_dir.mkdir()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file includes a substantial Chinese-only section that conveys core skill behavior, usage, and safety guidance before the English sections. Because the skill is not documented as region-specific or opt-in by locale, this can create a language/locale policy issue for users who are not expecting Chinese-only operational content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The docstring states "CN: Structural province/city/district patterns + keyword-gated," and the implementation only recognizes Chinese address labels for that region, which reflects a locale-specific constraint. Because no user opt-in or justification is provided in the natural-language description, this can be read as enforcing a specific language/locale policy for Chinese address detection.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.