fix: Phase 3 — command injection, unwrap/expect panics, unsigned image acceptance

- VPN key gen: replaced sh -c with format string (command injection) with
  safe stdin piping to wg pubkey
- Secrets manager: replaced .unwrap() on path.parent() with proper error
- Tor proxy: replaced .expect("valid proxy") with continue on error
- Image verifier: added require_signatures flag, strict mode rejects
  unsigned images and missing cosign binary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-18 00:45:15 +00:00
parent 430d174389
commit 7bbb9cc5cd
5 changed files with 51 additions and 28 deletions

View File

@@ -190,7 +190,7 @@
> server (command injection) or crash your entire node at will (unwrap panic). These are the most
> dangerous code-level bugs found.
- [ ] **Fix command injection in VPN key generation**: In `core/archipelago/src/vpn.rs`, find lines 132-137 where `sh -c` is used with `format!("echo '{}' | wg pubkey", private_key)`. This is a textbook command injection vulnerability. Replace the entire block with safe stdin piping:
- [x] **Fix command injection in VPN key generation**: In `core/archipelago/src/vpn.rs`, find lines 132-137 where `sh -c` is used with `format!("echo '{}' | wg pubkey", private_key)`. This is a textbook command injection vulnerability. Replace the entire block with safe stdin piping:
```rust
let mut child = tokio::process::Command::new("wg")
.arg("pubkey")
@@ -223,7 +223,7 @@
Build: `cd ~/archy/core && cargo clippy --all-targets --all-features`.
Test: If VPN setup is available in the UI, test generating a WireGuard key.
- [ ] **Fix unwrap crash in secrets manager**: In `core/security/src/secrets_manager.rs`, find line 112 with `secret_path.parent().unwrap()`. Replace with:
- [x] **Fix unwrap crash in secrets manager**: In `core/security/src/secrets_manager.rs`, find line 112 with `secret_path.parent().unwrap()`. Replace with:
```rust
let parent = secret_path.parent()
.ok_or_else(|| anyhow::anyhow!("Invalid secret path: no parent directory for {:?}", secret_path))?;
@@ -232,7 +232,7 @@
Search for ALL `.unwrap()` calls in the file: `grep -n "unwrap()" core/security/src/secrets_manager.rs`. For each one in a non-test function, evaluate whether it can actually fail and replace with `?` or `.ok_or_else()` if so. Common safe unwraps (e.g., after a `.is_some()` check) can stay but should get a comment explaining why they're safe.
Build and deploy.
- [ ] **Fix expect crash in Tor proxy fallback**: In `core/archipelago/src/api/rpc/tor.rs`, find line ~525 with `.expect("valid proxy")`. Replace the entire proxy chain with proper error handling:
- [x] **Fix expect crash in Tor proxy fallback**: In `core/archipelago/src/api/rpc/tor.rs`, find line ~525 with `.expect("valid proxy")`. Replace the entire proxy chain with proper error handling:
```rust
let proxy_url = format!("socks5h://{}", proxy);
let proxy = reqwest::Proxy::all(&proxy_url)
@@ -242,7 +242,7 @@
Search for ALL `.expect(` calls in non-test code: `grep -rn "\.expect(" core/archipelago/src/ --include="*.rs" | grep -v "#\[cfg(test)\]" | grep -v "mod tests"`. List them and fix any that could realistically fail in production.
Build: `cargo clippy --all-targets --all-features`.
- [ ] **Fix image verifier accepting unsigned images**: In `core/security/src/image_verifier.rs`, find lines 18-22 where the verifier returns `Ok(false)` for unsigned images. Change to:
- [x] **Fix image verifier accepting unsigned images**: In `core/security/src/image_verifier.rs`, find lines 18-22 where the verifier returns `Ok(false)` for unsigned images. Change to:
```rust
if signature.is_none() && self.cosign_public_key.is_none() {
return Err(anyhow::anyhow!(
@@ -262,7 +262,7 @@
```
Build and test. Note: this may cause existing unsigned images to fail verification. If the system doesn't use cosign yet, add a config flag `require_signatures: bool` that defaults to `false` for now but can be flipped to `true` when cosign is deployed.
- [ ] **Verify Phase 3 — No more crash vectors**: Run these checks:
- [x] **Verify Phase 3 — No more crash vectors**: Run these checks:
1. `grep -rn 'Command::new("sh")' core/ --include="*.rs"` — should return zero results.
2. `grep -rn "\.unwrap()" core/security/src/secrets_manager.rs | grep -v test` — should be minimal/commented.
3. `grep -rn "\.expect(" core/archipelago/src/api/ --include="*.rs" | grep -v test | grep -v "// SAFE:"` — review each remaining expect.