Back to skill

Security audit

Soul Undead

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent backup/restore purpose, but its script can overwrite sensitive agent files and can follow symlinks outside the intended workspace scope.

Install only if you intentionally want these core OpenClaw files copied to a private GitHub repo and restored from it. Before running, inspect the target repo and local files, avoid symlinked tracked files, and be aware that first initialization can overwrite local agent identity, memory, and instruction files from remote content.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/init_or_sync.sh:90
Finding

Tracked Workspace Symlinks Can Exfiltrate Arbitrary Readable Files

Content
View full analysis
/dev/null || true)" if [ -n "$response_sha" ]; then gh api -X PUT "$api_path" \ -f message="Sync $remote_name from OpenClaw workspace" \ -f content="$content_b64" \ -f sha="$response_sha" >/dev/null else gh api -X PUT "$api_path" \ -f message="Add $remote_name from OpenClaw workspace" \ -f content="$content_b64" >/dev/null fi } ``` ```bash for f in "${FILES[@]}"; do if [ -f "$WORKSPACE_DIR/$f" ]; then upsert_remote_file "$WORKSPACE_DIR/$f" "$f" changed=true echo "Synced: $f" fi done ``` ### Technical Analysis The synchronization loop checks tracked paths with `-f`, but this test succeeds when the path is a symbolic link whose target is a regular file. The script does not reject symbolic links or verify that the canonical path remains inside `WORKSPACE_DIR`. The accepted path is passed to `upsert_remote_file`, where shell input redirection follows the symbolic link: ```bash base64 < "$file_path" ``` The target file is encoded and uploaded through the authenticated GitHub API. Consequently, a party capable of creating or replacing one of the seven tracked workspace entries can make the script upload any file readable by the user running the skill. Quoting prevents shell command injection, but it does not prevent filesystem redirection through symbolic links. ### Attack Path 1. An attacker obtains the ability to create or replace a file in the OpenClaw workspace, ...[truncated 1220 chars]
Remediation
View remediation
&2 exit 1 fi if [ -f "$path" ]; then resolved_path="$(realpath -- "$path")" resolved_workspace="$(realpath -- "$WORKSPACE_DIR")" case "$resolved_path" in "$resolved_workspace"/*) ;; *) echo "Tracked file resolves outside the workspace: $path" >&2 exit 1 ;; esac upsert_remote_file "$resolved_path" "$f" fi ``` Additional hardening should include: - Require every tracked entry to be a regular, non-symlink file. - Verify that each canonical path remains under the canonical workspace directory. - Consider requiring files to be owned by the invoking user. - Open files defensively with no-follow semantics where supported, rather than performing a check followed by a separate read. - Revalidate immediately before reading to reduce time-of-check/time-of-use race exposure. - Abort synchronization if a tracked entry has an unexpected filesystem type. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/init_or_sync.sh:71
Finding

Destination Symlinks Can Redirect Restored Content Outside the Workspace

Content
View full analysis
/dev/null 2>&1 for f in "${FILES[@]}"; do if [ -f "$tmpdir/repo/$f" ]; then cp "$tmpdir/repo/$f" "$WORKSPACE_DIR/$f" echo "Restored: $WORKSPACE_DIR/$f" fi done } ``` ### Technical Analysis The restore process validates that each source from the cloned repository is a regular file, but it does not validate the corresponding destination in the workspace. If a destination such as `$WORKSPACE_DIR/AGENTS.md` is an existing symbolic link, the `cp` operation can follow that link and write the remote content to its target. This allows an attacker who can prepare workspace entries to redirect restoration outside the intended workspace boundary. The pre-restore snapshot does not prevent exploitation. Its own regular-file checks may also follow workspace symlinks, and retaining a backup does not stop the subsequent overwrite of the external target. ### Attack Path 1. An attacker gains permission to modify entries in the OpenClaw workspace. 2. The attacker replaces a tracked destination with a symbolic link to another file writable by the user: ```bash ln -sf "$HOME/.config/example/config.md" \ "$HOME/.openclaw/workspace/AGENTS.md" ``` 3. The state file is absent or reports that initialization has not completed. 4. The configured GitHub repository exists and contains `AGENTS.md`. 5. The user runs `scripts/init_or_sync.sh`. 6. The script enters the first-time restore path and clones the repository. 7. `cp "$tmpdir/repo/AGENTS.md" "$WORKSPACE_DIR/AGENTS.md"` follows the prepared destination link ...[truncated 715 chars]
Remediation
View remediation
&2 exit 1 fi workspace_real="$(realpath -- "$WORKSPACE_DIR")" destination_parent="$(realpath -- "$(dirname -- "$destination")")" if [ "$destination_parent" != "$workspace_real" ]; then echo "Destination is outside the workspace: $destination" >&2 exit 1 fi temporary="$(mktemp "$WORKSPACE_DIR/.restore.XXXXXX")" cp -- "$tmpdir/repo/$f" "$temporary" chmod --reference="$tmpdir/repo/$f" "$temporary" 2>/dev/null || chmod 600 "$temporary" mv -T -- "$temporary" "$destination" ``` The implementation should also: - Reject non-regular source and destination types. - Avoid following links during backup snapshot creation. - Use platform-appropriate no-follow APIs if portability permits. - Ensure cleanup of temporary files on all failure paths. - Consider requiring explicit confirmation before overwriting any existing destination. ]]>

T02 · Agent Memory Poisoning

Warning
Location
scripts/init_or_sync.sh:71
Finding

Unverified Remote Content Can Replace Persistent Agent Instructions and Memory

Content
View full analysis
/dev/null 2>&1 for f in "${FILES[@]}"; do if [ -f "$tmpdir/repo/$f" ]; then cp "$tmpdir/repo/$f" "$WORKSPACE_DIR/$f" echo "Restored: $WORKSPACE_DIR/$f" fi done } ``` ```bash if [ "$(is_initialized)" != "true" ]; then if repo_exists; then echo "First initialization: remote repo exists, restoring local files first." restore_from_remote write_initialized echo "Initialization complete." exit 0 ``` ### Technical Analysis During first initialization, the script treats the current contents of the configured GitHub repository as authoritative. It directly replaces persistent OpenClaw files including: - `AGENTS.md` - `IDENTITY.md` - `SOUL.md` - `TOOLS.md` - `USER.md` - `MEMORY.md` These files can influence the Agent's instructions, identity, available-tool guidance, user context, and long-term behavior. The restore process authenticates access to GitHub, but authentication alone does not establish that the repository contents are safe, expected, or unchanged. The script does not: - Pin or verify an expected commit. - Verify signed commits. - Display a content diff. - Require per-restore confirmation. - Validate the semantic content of instruction or memory files. - Record and verify an immutable repository identifier. A compromised GitHub account, compromised repository collaborator, incorrectly configured owner, or unexpected repository state can therefore cause persistent attacker-controlled instructions to be installed locally. The documented snapshot supports rollback, ...[truncated 1542 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that restore operations can overwrite local core workspace files and only mentions a backup as rollback safety, without a prominent warning or explicit confirmation requirement. For a skill that manages identity-, memory-, and agent-related markdown files, undocumented or weakly signposted overwrite behavior can cause accidental loss, confusion, or restoration of stale or attacker-controlled state.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs reading and writing sensitive workspace files and creating local backup snapshots, but it does not declare an explicit tool scope such as allowed-tools or permissions. That mismatch can cause the runtime to grant broader-than-expected capabilities or leave operators without a clear boundary on what file operations the skill is permitted to perform.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- Always check `gh auth status` first.
- If GitHub authentication is missing, stop and tell the user to run `gh auth login`.
- Do not scan the whole workspace.
- Do not ask the user to choose files unless they explicitly ask for a different scope.
- Treat the fixed GitHub repo as the authority during first-time initialization on a new machine.
- Before any remote restore overwrites local files, create a timestamped local backup snapshot under `skills/soul-undead/local-backups/`.
- Do not keep a persistent local export mirror; sync should act directly on the GitHub private repo.

Session Persistence

Medium
Category
Rogue Agent
Confidence
87% confidence
Finding

The skill creates timestamped local backup snapshots of core identity and memory markdown files under a persistent directory. Those files may contain sensitive persona, memory, or user-related data, and retaining them indefinitely increases exposure if the local machine or workspace is later accessed by another process or user.

Content

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

md
- Do not scan the whole workspace.
- Do not ask the user to choose files unless they explicitly ask for a different scope.
- Treat the fixed GitHub repo as the authority during first-time initialization on a new machine.
- Before any remote restore overwrites local files, create a timestamped local backup snapshot under `skills/soul-undead/local-backups/`.
- Do not keep a persistent local export mirror; sync should act directly on the GitHub private repo.

## Important behavior: first restore can overwrite local default files

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script restores files from a remote GitHub repository directly into the local workspace, overwriting local copies of identity, memory, and agent configuration files without an explicit confirmation step at the point of replacement. It also uploads those same files to GitHub during sync, which can expose sensitive workspace data if the user is unaware, the repository owner is mis-set, or the repository later becomes accessible.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

This skill intentionally creates a persistent private GitHub repository and stores long-lived workspace files there, establishing external session/state persistence outside the local environment. In this context the persisted files include AGENTS.md, IDENTITY.md, USER.md, MEMORY.md, and similar core state, so a compromise of the GitHub account, accidental misconfiguration, or later repository exposure could leak sensitive agent or user data.

Content

Scanner excerpt · scripts/init_or_sync.sh (reported line 123)May include surrounding context.

sh
local tmpdir restore_path readme_path

  if ! repo_exists; then
    gh repo create "$GITHUB_OWNER/$REPO_NAME" --private --description 'OpenClaw workspace core markdown files' >/dev/null
  fi

  for f in "${FILES[@]}"; do

Static analysis

No suspicious patterns detected.