Commit graph

16 commits

Author SHA1 Message Date
Chummy
918be53a30 test(security): harden token format regression coverage 2026-02-18 16:56:45 +08:00
Mike Boensel
0166f2d4de fix(token): update token generation to use rand::rng() to resolve deprecation warnings 2026-02-18 02:11:51 -05:00
DeadManAI
4fca1abee8 fix: resolve all clippy warnings, formatting, and Mistral endpoint
- Fix Mistral provider base URL (missing /v1 prefix caused 404s)
- Resolve 55 clippy warnings across 28 warning types
- Apply cargo fmt to 44 formatting violations
- Remove unused imports (process_message, MultiObserver, VerboseObserver,
  ChatResponse, ToolCall, Path, TempDir)
- Replace format!+push_str with write! macro
- Fix unchecked Duration subtraction, redundant closures, clamp patterns
- Declare missing feature flags (sandbox-landlock, sandbox-bubblewrap,
  browser-native) in Cargo.toml
- Derive Default where manual impls were redundant
- Add separators to long numeric literals (115200 → 115_200)
- Restructure unreachable code in arduino_flash platform branches

All 1,500 tests pass. Zero clippy warnings. Clean formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 20:00:08 +08: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
Argenis
dc5a85c85c
fix: use 256-bit entropy for pairing tokens (#351)
Merges #413
2026-02-16 13:48:03 -05:00
Edvard Schøyen
bd02d73ecc
test: add comprehensive pairing code consumption tests
Add comprehensive tests for pairing code consumption feature
2026-02-15 07:36:54 -05:00
argenis de la rosa
7a03a01fbf Merge remote-tracking branch 'origin/main' into fix/bearer-token-hashing
# Conflicts:
#	src/security/pairing.rs
2026-02-14 21:51:28 -05:00
fettpl
2f2f56fc0c fix: use branchless operations in constant_time_eq
- Use bitwise & instead of && to avoid short-circuit timing leak
- Use get().unwrap_or(&0) instead of if/else for branchless byte access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:30:23 +01:00
fettpl
23048d10ac refactor: simplify hash_token using format macro
Replace manual hex encoding loop with `format!("{:x}", Sha256::digest(...))`,
which is more idiomatic and concise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:28:04 +01:00
fettpl
6776373e8e fix: constant_time_eq no longer leaks secret length via early return
Remove the early return on length mismatch that leaked length
information via timing. Now iterates over max(a.len(), b.len()),
padding the shorter input with zeros, and checks both byte-level
differences and length equality at the end.

Closes #57

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:01:23 +01:00
fettpl
b3bfbaff4a fix: store bearer tokens as SHA-256 hashes instead of plaintext
Hash paired bearer tokens with SHA-256 before storing in config and
in-memory. When authenticating, hash the incoming token and compare
against stored hashes. Backward compatible: existing plaintext tokens
(zc_ prefix) are detected and hashed on load; already-hashed tokens
(64-char hex) are stored as-is.

Closes #58

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:58:09 +01:00
Víctor R. Escobar
1c8fe79238 fix: address PR review — rejection sampling and robust test
- Use rejection sampling to eliminate modulo bias in generate_code().
  Values above the largest multiple of 1_000_000 in u32 are discarded
  and re-drawn (~0.02% rejection rate).
- Make generate_code_is_not_deterministic test robust against the
  1-in-10^6 collision chance by trying 10 pairs instead of one.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 13:48:36 +01:00
Víctor R. Escobar
15a58eb7da fix: use CSPRNG for pairing code generation
Replace DefaultHasher + SystemTime + process::id() with UUID v4
(backed by getrandom/urandom CSPRNG) for pairing code generation.

The previous implementation used predictable entropy sources
(system time to ~1s precision and process ID) with a non-cryptographic
hash (SipHash), making the 6-digit code brute-forceable.

The new implementation extracts 4 random bytes from a UUID v4
(which uses the OS CSPRNG) and derives the 6-digit code from those.
No new dependencies added — reuses existing uuid crate.

Adds a test verifying non-deterministic output.

Ref: CWE-330 (Use of Insufficiently Random Values)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 13:29:58 +01:00
argenis de la rosa
976c5bbf3c hardening: fix 7 production weaknesses found in codebase scan
Scan findings and fixes:

1. Gateway buffer overflow (8KB → 64KB)
   - Fixed: Increased request buffer from 8,192 to 65,536 bytes
   - Large POST bodies (long prompts) were silently truncated

2. Gateway slow-loris attack (no read timeout → 30s)
   - Fixed: tokio::time::timeout(30s) on stream.read()
   - Malicious clients could hold connections indefinitely

3. Webhook secret timing attack (== → constant_time_eq)
   - Fixed: Now uses constant_time_eq() for secret comparison
   - Prevents timing side-channel on webhook authentication

4. Pairing brute force (no limit → 5 attempts + 5min lockout)
   - Fixed: PairingGuard tracks failed attempts with lockout
   - Returns 429 Too Many Requests with retry_after seconds

5. Shell tool hang (no timeout → 60s kill)
   - Fixed: tokio::time::timeout(60s) on Command::output()
   - Commands that hang are killed and return error

6. Shell tool OOM (unbounded output → 1MB cap)
   - Fixed: stdout/stderr truncated at 1MB with warning
   - Prevents memory exhaustion from verbose commands

7. Provider HTTP timeout (none → 120s request + 10s connect)
   - Fixed: All 5 providers (OpenRouter, Anthropic, OpenAI,
     Ollama, Compatible) now have reqwest timeouts
   - Ollama gets 300s (local models are slower)

949 tests passing, 0 clippy warnings, cargo fmt clean
2026-02-14 01:47:08 -05: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