Back to skill

Security audit

Session Daily Backup - Obsidian

Security checks for vulnerabilities and agentic risk

Overview

This skill openly backs up OpenClaw conversations to Obsidian, but it handles sensitive chat history broadly and persistently without enough privacy, permission, or retention controls.

Install only if you intentionally want OpenClaw chat history copied into plaintext Obsidian files. Use a private vault, avoid syncing sensitive backups, run the scripts as a least-privileged user, add restrictive permissions such as umask 077, disable QQ notifications unless needed, and review or remove the cron job when you no longer want automatic backups.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/save_full_snapshot.sh:23
Finding

Path Traversal Through Unsanitized Snapshot Topic

Content
View full analysis
"$SNAPSHOT_FILE" <` redirection then creates or truncates the resolved `.md` file using the privileges of the account running the script. The timestamp prefix and forced `.md` suffix constrain the exact filename but do not prevent traversal into another directory. Existing symbolic links at a predicted destination can also redirect the write to another writable target. ### Attack Path 1. An attacker gains the ability to control the topic argument passed to `save_full_snapshot.sh`, such as through untrusted automation, a wrapper, or direct local invocation. 2. The attacker supplies a topic containing directory traversal components, for example: ```bash bash scripts/save_full_snapshot.sh "../../../../tmp/attacker-controlled" ``` 3. The script concatenates the unvalidated value with `VAULT_DIR` and the timestamp. 4. The operating system resolves the `../` components outside the configured Obsidian vault. 5. The `cat > "$SNAPSHOT_FILE"` operation creates or truncates the resulting `.md` file. 6. The script writes session metadata and conversation contents into that destination. If a predict ...[truncated 616 chars]
Remediation
View remediation
&2 exit 1 fi ``` 2. Explicitly reject `/`, `\`, control characters, and traversal components. 3. Create the vault directory and resolve its canonical path before writing: ```bash mkdir -p -- "$VAULT_DIR" VAULT_REAL=$(realpath -- "$VAULT_DIR") SNAPSHOT_FILE="$VAULT_REAL/$TIMESTAMP-$TOPIC.md" ``` 4. Verify that the canonical parent directory of the destination remains equal to the canonical vault directory. 5. Defend against symbolic-link attacks by refusing existing symlink destinations and, where possible, creating output files with no-follow and exclusive-creation semantics. 6. Run the script as a dedicated unprivileged user with write access only to the intended vault and tracking directories. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/monitor_and_save.sh:105
Finding

Sensitive Conversation Backups Are Created Without Restrictive Permissions

Content
View full analysis
"$snapshot_file" <> "$snapshot_file" echo "---" >> "$snapshot_file" echo "" >> "$snapshot_file" echo "## 新增对话 - $(date '+%H:%M')" >> "$snapshot_file" echo "" >> "$snapshot_file" fi # 备份所有 session 文件 local saved_count=0 for session_file in "${session_files[@]}"; do local session_name=$(basename "$session_file" .jsonl) local session_lines=$(wc -l < "$session_file") echo "" >> "$snapshot_file" echo "### 📁 Session: $session_name ($session_lines 行)" >> "$snapshot_file" echo "" >> "$snapshot_file" # 转换整个 session 为 markdown cat "$session_file" | while IFS= read -r line; do echo "$line" | jq -r -f "$FORMAT_JQ" 2>/dev/null done >> "$snapshot_file" saved_count=$((saved_count + session_lines)) done ``` From `scripts/save_full_snapshot.sh`: ```bash cat > "$SNAPSHOT_FILE" </dev/null done >> "$SNAPSHOT_FILE" ``` From `scripts/create_hourly_snapshots.sh`: ``` ...[truncated 2705 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly promotes automatic backup of session conversations into local Obsidian markdown files but does not warn that chats may contain secrets, personal data, credentials, or other sensitive content that will be persisted outside the original application. In the context of AI session logs, silent persistence materially increases confidentiality risk because users may not realize their prompts and responses are being copied into a long-lived, searchable vault.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The README instructs users to create a cron job that automatically runs a script to process and persist session data daily, establishing ongoing session persistence. In this skill's context, that persistence is more sensitive because the data being copied consists of AI conversation history, which may include confidential prompts, tokens, operational details, or personal information, and the automation increases the chance of unnoticed long-term retention.

Content

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

bash
# 编辑 crontab
crontab -e

# 添加每日凌晨 2 点备份
0 2 * * * bash /path/to/session-daily-backup-obsidian/scripts/monitor_and_save.sh >> /path/to/backup.log 2>&1

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 151)May include surrounding context.

查看当前 cron 任务

bash
crontab -l

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly backs up conversation content to an Obsidian vault and can send token-related alerts via QQ, but the documentation does not warn users that sensitive chat content or metadata may be persisted outside the primary system. This creates a real privacy and data-handling risk because users may enable the skill without understanding retention, local storage, or third-party notification implications.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
87% confidence
Finding

The documented cron job establishes persistent, automated collection and storage of session data, which increases the blast radius of any misconfiguration, over-collection, or unauthorized access to the backup location. In this context, persistence is security-relevant because it continuously processes potentially sensitive conversations and writes logs under root-owned paths without any documented access controls or retention limits.

Content

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

bash
# 编辑 crontab
crontab -e

# 添加每日凌晨 2 点备份
0 2 * * * bash /root/.openclaw/workspace/skills/session-daily-backup-obsidian/scripts/monitor_and_save.sh >> /root/clawd/backup.log 2>&1

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest description is written entirely in Chinese, which may indicate the skill is intended to operate in a specific language without stating that this is optional or region-specific. The policy requires either user language choice or a clearly justified locale restriction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script automatically exports conversation content from the latest session JSONL into markdown files under a vault directory without any explicit confirmation, warning, or access-control check. This creates a real data exposure risk because potentially sensitive prompts, responses, or secrets may be copied into a broader-syncing or less-restricted notes location, increasing the chance of unintended disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script transmits conversation-derived status data to external QQ messaging channels via either the openclaw CLI or an HTTP API, but this file provides no explicit consent, disclosure, or restriction around that transmission. Even though the current message body is a token warning rather than raw chat content, it still leaks metadata about private conversations and can expose usage patterns or sensitive operational context to external services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code performs an outbound HTTP request to a configured QQ bot endpoint and includes conversation-derived warning content in the payload. Any external transmission path increases confidentiality risk, and because the URL is fully configurable, misconfiguration or a hostile endpoint could capture metadata or relay notifications to unintended recipients.

Content

Scanner excerpt · scripts/monitor_and_save.sh (reported line 66)May include surrounding context.

sh
# 方法 2: 使用 go-cqhttp API(如果配置了)
    if [[ -n "$QQ_BOT_URL" ]]; then
        curl -s -X POST "$QQ_BOT_URL/send_private_msg" \
            -H "Content-Type: application/json" \
            -d "{\"user_id\": \"$QQ_USER_ID\", \"message\": \"$message\"}" > /dev/null
        return $?

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script automatically converts all session JSONL files into markdown and writes them into a vault directory, effectively duplicating potentially sensitive conversations into another storage location without any access-control checks or safety prompts. This broad backup behavior increases exposure of secrets, prompts, credentials, or personal data contained in sessions, especially if the vault is synced, indexed, or shared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This script copies the latest session JSONL into a persistent markdown file in an Obsidian vault without any confirmation, warning, filtering, or redaction. Session logs can contain sensitive prompts, secrets, tokens, personal data, or internal reasoning, so creating an easily browsable snapshot materially increases the risk of unintended disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The natural-language content throughout the README is entirely Chinese, including usage instructions and warnings, which can amount to a locale/language constraint when no alternative or opt-in is provided. The file does not indicate that the skill is region-specific or that users may choose another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language instructions and operational details are presented exclusively in Chinese, which imposes a specific language on users without any opt-in or alternative. Under the stated policy, forcing a specific language without user choice is a natural-language policy concern unless the locale constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This manifest description explains what the skill does but provides no explicit activation phrases, invocation boundaries, or exclusion conditions. For a manifest file, that lack of trigger specificity can lead to ambiguous or overly broad invocation behavior if the platform relies on description text for routing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file contains user-visible comments and output/messages entirely in Chinese, including the stated behavior description on line 3. Under the stated policy, forcing a specific language without offering choice or documenting a justified locale constraint is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.