KeiSeiKit-1.0/_primitives/_rust/keisei/Cargo.toml
Parfii-bot d32ca0bc28 fix(v0.19): audit hardening — 3 security HIGH + 3 critic HIGH + 2 critic MEDIUM
Closes consolidated findings from wave-audit (critic + security + architect):

SECURITY HIGH:
  H1 path escape — Brain::load rejects absolute mcp_server paths +
    any containing '..'; canonicalize + starts_with(root) assertion;
    new Error::PathEscape variant.
  H2 brain name validation + clobber refuse — regex ^[a-z][a-z0-9_-]{0,63}$
    enforced at Brain::load; adapters refuse to overwrite existing
    mcpServers[name] with NameConflict (unless same content).
  H3 symlink reject at canonicalize — std::fs::symlink_metadata()
    called before canonicalize; Error::BrainIsSymlink with resolved
    target path; prevents USB → $HOME pivot.

CRITIC HIGH:
  #1 rusqlite dep deleted (zero uses in src/, pulls C toolchain).
  #3 BrainPaths memory/artifacts/manifests now Option<String>
    (only mcp_server required; schema no longer lies about contract).

CRITIC MEDIUM:
  #1 _primitives/_rust/keisei/src/paths.rs (new, 23 LOC) — SSoT for
    $KEISEI_HOME/$HOME resolver; config.rs and claude_code.rs
    delegate instead of duplicating 7-line block.
  #2 canonicalize error preserves io::Error via new Error::BrainLoad
    { path, source } with #[source] attribute.
  #5 fsx::write_atomic_json rewrite via tempfile::NamedTempFile
    + persist — Windows-safe, cross-fs-fallback handling.

New module split (Constructor Pattern): brain.rs (104 → 122) now a
thin orchestrator over brain_validate.rs (108 LOC) which owns
symlink-reject / canonicalize-root / read-manifest / validate-schema
/ validate-name / check-relative-in-root / canonicalize-in-root.

Deps: regex = { workspace = true }, tempfile = "3" (runtime).
Workspace-level regex = "1.10" added.
MANIFEST.toml [primitive.keisei] deps updated.

Tests: 11 pre-existing + 5 adversarial:
  - manifest_with_absolute_mcp_server_rejected — proves /usr/bin/python3
    CANNOT land in settings.json (PathEscape + marker absent asserts)
  - manifest_with_parent_traversal_rejected — ../../etc/passwd rejected
  - manifest_with_invalid_name_rejected — 'claude-ide!' rejected
  - brain_path_is_symlink_rejected — USB → $HOME pivot blocked
  - attach_refuses_to_clobber_existing_mcp_entry — NameConflict on diff

All 16 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:36:11 +08:00

23 lines
537 B
TOML

[package]
name = "keisei"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
description = "Exobrain attach/status CLI — mounts a portable brain (memory + manifests + artifacts + MCP bin) into an AI client (MVP: Claude Code)"
[[bin]]
name = "keisei"
path = "src/main.rs"
[dependencies]
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
toml = "0.8"
thiserror = "2"
regex = { workspace = true }
tempfile = "3"
[dev-dependencies]
tempfile = "3"