T09 · Insecure Skill Coding Practices
- Location
guard.mjs:377- Finding
Bash allowlist permits file-write bypasses on protected branches and paths
- Content
View full analysis
openclaw.json" and "echo > ~/.openclaw/..." bypass // class Parker surfaced on 2026-04-19. /(>>?|\btee\b).*\.openclaw\/openclaw\.json\b/, // OpenClaw main config /(>>?|\btee\b).*\.openclaw\/agents\/[^\/\s|;&]+\/agent\/(auth-profiles|settings)\.json\b/, // agent auth/settings /(>>?|\btee\b).*\.openclaw\/(extensions|credentials|secrets)\/[^\s|;&]+/, // deployed exts, imessage pairing, SA token /(>>?|\btee\b).*\.ldm\/extensions\/[^\s|;&]+/, // LDM OS deployed extensions /(>>?|\btee\b).*\.ldm\/config\.json\b/, // LDM OS root config /(>>?|\btee\b).*\.ldm\/agents\/[^\/\s|;&]+\/config\.json\b/, // LDM OS agent configs ``` ```js // guard.mjs:377-388 function stripQuotedContent(cmd) { return cmd.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""'); } // Check each segment of a compound command independently. // "rm -f file ; echo done" splits into ["rm -f file", "echo done"]. // Each segment checked against blocked, then allowed. An allowed match // on one segment can't excuse a blocked match on a different segment (#232). function isBlockedCompoundCommand(cmd, blockedPatterns, allowedPatterns) { const stripped = stripQuotedContent(cmd); const segments = stripped.split(/\s*(?:&&|\|\||[;|])\s*/).filter(Boolean); for (const segment of segments) { ...[truncated 4539 chars]- Remediation
View remediation
relative-file` - `printf x >> relative-file` - `cat source > relative-file` - `curl -o relative-file URL` - Quoted absolute destinations - `$HOME` and tilde-expanded protected destinations - Redirections within pipelines and compound commands - Symlinks pointing from an allowed location to a protected destination ]]>
