T05 · Unauthorized Access and Privilege Escalation
- Location
reference.md:5- Finding
Root LaunchDaemon Executes User-Writable Caddy Binary and Configuration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is coherent Caddy setup guidance, but it needs Review because it recommends weakened gateway authentication and privileged persistent proxy setup without enough hardening.
Review before installing. Prefer loopback-only backend bindings, keep OpenClaw device authentication enabled unless you add strong compensating access controls, pin and verify the Caddy/plugin build, avoid running user-writable binaries as root, and store Vercel tokens with restrictive permissions and limited scope.
reference.md:5Root LaunchDaemon Executes User-Writable Caddy Binary and Configuration
OPENCLAW.md:14OpenClaw Device Authentication Is Explicitly Disabled
reference.md:68Backend Applications Are Unnecessarily Exposed on All Network Interfaces
reference.md:176Unpinned External Dependencies Are Incorporated into a Privileged Proxy Binary
reference.md:253Long-Lived Vercel DNS Credentials Are Stored Without Required File-Permission Hardening
The service is configured to load secrets from a plain-text environment file, and the broader guide centers DNS API credentials needed for certificate automation. If that file is readable by other users, backed up insecurely, or accidentally committed, an attacker could gain control over DNS challenge operations and potentially broader Vercel resources depending on token scope.
[Service]
Type=simple
EnvironmentFile=%h/.secrets/vercel/.env
ExecStart=%h/.local/bin/caddy run --config %h/.config/caddy/Caddyfile
ExecReload=%h/.local/bin/caddy reload --config %h/.config/caddy/Caddyfile
Restart=always
The documentation explicitly instructs users to set allowInsecureAuth: true, which weakens authentication for the control UI by allowing token-only access in place of stronger device-key authentication. Although the file explains why this is needed for certain proxy setups, it does not clearly warn that this reduces security and may expose the gateway to unauthorized access if origins, tokens, or proxy boundaries are misconfigured.
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.
reference.md for templates~/.config/caddy/Caddyfile):
appname.YOUR_DOMAIN {
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
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.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
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.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
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.
sudo launchctl unload /Library/LaunchDaemons/com.caddyserver.caddy.plist sudo launchctl load /Library/LaunchDaemons/com.caddyserver.caddy.plist
systemctl --user restart caddy
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
**Port 443 on macOS:** Non-root processes can't bind ports <1024. Use a system LaunchDaemon (runs as root) with HOME/XDG_DATA_HOME/XDG_CONFIG_HOME env vars so Caddy can find cert storage.
**Port 443 on Linux:** Grant the capability once: `sudo setcap 'cap_net_bind_service=+ep' ~/.local/bin/caddy` — then a user service works fine.
## Example Apps
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
**Port 443 on macOS:** Non-root processes can't bind ports <1024. Use a system LaunchDaemon (runs as root) with HOME/XDG_DATA_HOME/XDG_CONFIG_HOME env vars so Caddy can find cert storage.
**Port 443 on Linux:** Grant the capability once: `sudo setcap 'cap_net_bind_service=+ep' ~/.local/bin/caddy` — then a user service works fine.
## Example Apps
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
**Port 443 on macOS:** Non-root processes can't bind ports <1024. Use a system LaunchDaemon (runs as root) with HOME/XDG_DATA_HOME/XDG_CONFIG_HOME env vars so Caddy can find cert storage.
**Port 443 on Linux:** Grant the capability once: `sudo setcap 'cap_net_bind_service=+ep' ~/.local/bin/caddy` — then a user service works fine.
## Example Apps
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
**Port 443 on macOS:** Non-root processes can't bind ports <1024. Use a system LaunchDaemon (runs as root) with HOME/XDG_DATA_HOME/XDG_CONFIG_HOME env vars so Caddy can find cert storage.
**Port 443 on Linux:** Grant the capability once: `sudo setcap 'cap_net_bind_service=+ep' ~/.local/bin/caddy` — then a user service works fine.
## Example Apps
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers
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.
**Port convention:** Permanent apps in the 3100 range, dev servers at 5200+ (managed by [dev-serve](https://clawhub.com/skills/dev-serve)).
**Vercel API Token:** Create a long-lived `vcp_*` token at https://vercel.com/account/tokens (no expiration — must be revoked if exposed). On macOS, store it in the LaunchDaemon plist env vars. On Linux, store it in an env file loaded by systemd (see Service Management below). You can push a new token to the live config without restart via `curl -X POST http://localhost:2019/load` with the token in the JSON config.
## Quick Dev Servers