Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .triage-state/phase0.json
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
{"phase":0,"context":{"mode":"interactive","environment":"CLI/agent harness; operator configuration is trusted, but repositories, models, skills, tool output, and MCP responses may be malicious.","threat_model":["Confused-deputy privilege escalation causing unauthorized host access, command execution, secret exposure, or network egress."],"scoring":"Derived HIGH/MEDIUM/LOW from preconditions","noise_tolerance":"precision","votes_per_finding":3,"repo":"/home/jg/git/bee","findings_path":"/home/jg/git/bee/VULN-FINDINGS.json"}}
{
"phase": 0,
"context": {
"mode": "interactive",
"environment": "CLI/batch tool and interactive REPL. Operator-supplied configuration and direct operator inputs are trusted; repository files, scenarios, project configuration, model output, tool output, skills, and MCP content are untrusted.",
"threat_model": [
"Privilege escalation to administrator or root (highest priority)",
"Sandbox or confinement escape (highest priority)",
"Host credential and sensitive-data exposure",
"Supply-chain compromise of downstream users",
"Unauthorized network or service access",
"Integrity loss in policy, audit, transcript, or evaluation evidence",
"Denial of service through algorithmic or unbounded in-process work"
],
"scoring": "Derived HIGH/MEDIUM/LOW from preconditions",
"noise_tolerance": "precision",
"votes_per_finding": 3,
"repo": "/home/jg/git/bee",
"findings_path": "/home/jg/git/bee/VULN-FINDINGS.json"
}
}
29 changes: 28 additions & 1 deletion .triage-state/phase1.json

Large diffs are not rendered by default.

42 changes: 41 additions & 1 deletion .triage-state/phase2.json

Large diffs are not rendered by default.

986 changes: 18 additions & 968 deletions .triage-state/phase3.json

Large diffs are not rendered by default.

1,239 changes: 35 additions & 1,204 deletions .triage-state/phase4.json

Large diffs are not rendered by default.

1,241 changes: 10 additions & 1,231 deletions .triage-state/phase5.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .triage-state/progress.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"status": "complete", "phase_done": 6, "shards_done": [], "updated": "2026-07-21T19:07:24.256156+00:00"}
{"status": "complete", "phase_done": 6, "shards_done": [], "updated": "2026-07-23T15:18:36.305770+00:00"}
2 changes: 1 addition & 1 deletion .triage-state/shard_f001.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":"f001","source_id":"F-001","source":"VULN-FINDINGS.json#0","source_format":"vuln_findings_json","file":"bee-core/src/attenuation.rs","line":62,"category":"capability-widening","severity":"HIGH","title":"Removing all child write grants disables the parent's default-deny write boundary","description":"Policy::check_filesystem validates only child entries, so an empty child map passes. Enforcement planning arms FLAG_FS_WRITE_DEFAULT_DENY only when the compiled child contains a write rule, and the kernel permits unmatched writes without that flag. Deleting the parent's final write grant is therefore treated as attenuation while widening unmatched writes from denied to allowed.","exploit_scenario":"A parent grants write only to /workspace. A delegated child supplies an empty filesystem map; derivation succeeds, the default-deny flag is omitted, and the child can modify same-UID writable paths outside /workspace unless explicitly denied.","preconditions":[],"recommendation":"Represent unmatched-write default behavior explicitly and preserve deny-all semantics during attenuation even when the child retains no write grants.","scanner_confidence":1.0,"missing_fields":["preconditions"],"absorbed":[],"verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["bee-cli/src/main.rs:104","bee-cli/src/main.rs:169","bee-core/src/attenuation.rs:54"],"rationale":"check_filesystem iterates only child entries, so an empty child succeeds (bee-core/src/attenuation.rs:63). The live CLI compiles the derived child directly (bee-cli/src/main.rs:169-184). Planning leaves FLAG_FS_WRITE_DEFAULT_DENY unset without a child write rule (bee-userspace/src/plan.rs:48), and unmatched writes are then allowed (bee-ebpf/src/main.rs:331); the parent boundary does not survive."}
{"id":"f001","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["src/app/config/mod.rs:361"],"rationale":"Untrusted project configuration can reach ceiling.derive at src/app/config/mod.rs:353-362. crates/core/src/attenuation.rs:62-90 checks only child filesystem entries and returns the unmerged request, while crates/ebpf/src/main.rs:331-335 allows unmatched reads, so an omitted parent deny concretely widens authority."}
2 changes: 1 addition & 1 deletion .triage-state/shard_f002.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":"f002","source_id":"F-002","source":"VULN-FINDINGS.json#1","source_format":"vuln_findings_json","file":"bee-core/src/attenuation.rs","line":159,"category":"capability-widening","severity":"HIGH","title":"An empty child executable allowlist turns restricted execution into unrestricted execution","description":"check_exec verifies only executable entries present in the child, so an empty list passes. Planning marks has_exec_rules false, scope installation omits EXEC_ALLOW, and bprm_check_security explicitly permits all execution when that map entry is absent.","exploit_scenario":"A parent permits only cargo and rustc. A child requests exec.allow = []; derivation succeeds and the child can execute bash, curl, interpreters, or any accessible binary.","preconditions":[],"recommendation":"Represent exec-policy activation independently of allowlist cardinality, install empty deny-all allowlists, and regression-test nonempty-parent to empty-child attenuation.","scanner_confidence":1.0,"missing_fields":["preconditions"],"absorbed":[],"verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["bee-cli/src/main.rs:169","bee-cli/src/main.rs:104"],"rationale":"The production child path passes the child through parent.derive at bee-cli/src/main.rs:169. check_exec iterates only child entries (bee-core/src/attenuation.rs:160-174), so an empty child succeeds; compilation/planning omit EXEC_ALLOW (bee-core/src/compiler.rs:102-113; bee-userspace/src/plan.rs:61-64), and the LSM permits all execution when the map entry is absent (bee-ebpf/src/main.rs:200-204)."}
{"id":"f002","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["src/app/config/mod.rs:361","src/app/session.rs:311","src/app/session.rs:312"],"rationale":"Protected defaults are introduced only during compilation at crates/core/src/compiler.rs:83-100, after attenuation. A specific child grant can pass crates/core/src/attenuation.rs:101-155 and then outrank or replace the injected protected rule during crates/userspace/src/plan.rs:151-173."}
2 changes: 1 addition & 1 deletion .triage-state/shard_f003.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":"f003","source_id":"F-003","source":"VULN-FINDINGS.json#2","source_format":"vuln_findings_json","file":"bee-core/src/attenuation.rs","line":177,"category":"capability-widening","severity":"HIGH","title":"An empty child network allowlist disables egress enforcement","description":"check_network validates only destinations present in the child, so an empty list passes. The planner omits FLAG_NET_ENFORCED when the resolved list is empty, and socket_connect allows all destinations when that flag is absent.","exploit_scenario":"A parent permits only crates.io:443. A child supplies network.allow = []; attenuation succeeds and the child can connect to arbitrary IPv4/IPv6 destinations and ports.","preconditions":[],"recommendation":"Encode network-policy activation separately from allowlist size, make an empty list enforce deny-all, and compare effective defaults during attenuation.","scanner_confidence":1.0,"missing_fields":["preconditions"],"absorbed":[],"verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["bee-cli/src/main.rs:104","bee-cli/src/main.rs:169"],"rationale":"check_network vacuously accepts an empty child list (bee-core/src/attenuation.rs:177; confirmed by bee-core/tests/attenuation.rs:95). Compilation produces no network rules, planning leaves FLAG_NET_ENFORCED unset (bee-userspace/src/plan.rs:45), and socket_connect permits every connection when that flag is absent (bee-ebpf/src/main.rs:99). The production path invokes derive at bee-cli/src/main.rs:169."}
{"id":"f003","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":9.7,"exclusion_rule":null,"refute_reasons":[],"first_links":["crates/userspace/src/loader.rs:14","crates/userspace/src/loader.rs:23","src/tools/bash.rs:48"],"rationale":"The loader attaches only socket_connect, file_open, and bprm_check_security at crates/userspace/src/loader.rs:13-32. Model-controlled scoped children from src/tools/bash.rs:43-55 can use connectionless UDP sendto/sendmsg without traversing crates/ebpf/src/main.rs:92-139."}
25 changes: 0 additions & 25 deletions .triage-state/shard_f004.json

This file was deleted.

4 changes: 1 addition & 3 deletions .triage-state/shard_f005.json
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{
"id":"f005","source_id":"F-005","source":"VULN-FINDINGS.json#4","source_format":"vuln_findings_json","file":"bee-ebpf/src/main.rs","line":142,"category":"filesystem-policy-bypass","severity":"HIGH","title":"Path rules can be bypassed by relinking or renaming denied files","description":"Filesystem enforcement occurs only at file_open and decides from the resolved pathname. No link, rename, unlink, truncate, or setattr hook binds protected inode identity to policy, so aliases and non-open mutations bypass the path rule.","exploit_scenario":"A same-UID process hard-links a protected file into an allowed project directory and opens the alias; file_open sees only the allowed pathname. Rename produces the same outcome where permissions permit.","preconditions":[],"recommendation":"Mediate inode-mutating operations and/or bind decisions to stable inode and mount identity; document and reject unsupported path-only guarantees.","scanner_confidence":1.0,"missing_fields":["preconditions"],"absorbed":[],"verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["bee-userspace/src/loader.rs:14","bee-ebpf/src/main.rs:142"],"rationale":"The loader attaches only socket_connect, file_open, and bprm_check_security (bee-userspace/src/loader.rs:14), leaving link and rename operations uncovered. file_open authorizes only the rendered path (bee-ebpf/src/main.rs:169-180), so a permitted hardlink alias is evaluated under its allowed name rather than the protected source path; README.md:72 acknowledges this gap."
}
{"id":"f005","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":9.3,"exclusion_rule":null,"refute_reasons":[],"first_links":["crates/userspace/src/loader.rs:14","crates/userspace/src/loader.rs:23","src/tools/bash.rs:48"],"rationale":"Only file_open mediates filesystem access in crates/userspace/src/loader.rs:13-32. The hook authorizes only the resolved alias path at crates/ebpf/src/main.rs:142-180, leaving metadata operations uncovered and allowing hard-link aliases to escape protected-name rules."}
1 change: 0 additions & 1 deletion .triage-state/shard_f006.json

This file was deleted.

19 changes: 1 addition & 18 deletions .triage-state/shard_f007.json
Original file line number Diff line number Diff line change
@@ -1,18 +1 @@
{
"id": "f007",
"verdict": "true_positive",
"vote_breakdown": {
"true_positive": 2,
"false_positive": 1,
"cannot_verify": 0
},
"confidence": 9,
"exclusion_rule": 8,
"refute_reasons": [
"implausible_trigger"
],
"first_links": [
"bee-harness/src/episode.rs:577"
],
"rationale": "materialize_workdir performs unanchored host writes before sandbox construction (bee-harness/src/episode.rs:518-538,577-619). Although scenario paths are trusted config, an untrusted repository can pre-place a symlink beneath a trusted relative target, so the winning votes found a reachable host-write escape."
}
{"id":"f007","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":8.3,"exclusion_rule":null,"refute_reasons":[],"first_links":["crates/userspace/src/loader.rs:14","src/tools/bash.rs:48"],"rationale":"Exec enforcement returns allow on bpf_d_path error at crates/ebpf/src/main.rs:218-226 and uses a fixed 4096-byte buffer. A model-controlled process reachable from src/tools/bash.rs:43-55 can build a longer resolved directory chain and invoke a short relative executable without any fallback identity check."}
17 changes: 1 addition & 16 deletions .triage-state/shard_f008.json
Original file line number Diff line number Diff line change
@@ -1,16 +1 @@
{
"id": "f008",
"verdict": "true_positive",
"vote_breakdown": {
"true_positive": 3,
"false_positive": 0,
"cannot_verify": 0
},
"confidence": 10,
"exclusion_rule": null,
"refute_reasons": [],
"first_links": [
"bee-harness/src/episode.rs:597"
],
"rationale": "run_episode resolves grants for every discovered skill before invocation (bee-harness/src/episode.rs:596-608; bee-harness/src/skills/grant.rs:147-183). Hidden or uninvoked malicious project skills can therefore globally register tools, and tool-only requests are outside the policy ceiling."
}
{"id":"f008","verdict":"false_positive","vote_breakdown":{"true_positive":0,"false_positive":3,"cannot_verify":0},"confidence":10.0,"exclusion_rule":"3","refute_reasons":["intentional_behavior"],"first_links":["crates/ebpf/src/main.rs:180"],"rationale":"The no-match behavior exactly implements the documented filesystem contract at specs/001-ebpf-agent-sandbox/contracts/policy.schema.md:45-54: unmatched reads are allowed and unmatched writes are denied only after a positive write grant activates managed-write mode. All three verifiers found this to be intended design under exclusion rule 3."}
20 changes: 1 addition & 19 deletions .triage-state/shard_f009.json
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@
{
"id": "f009",
"verdict": "false_positive",
"vote_breakdown": {
"true_positive": 1,
"false_positive": 2,
"cannot_verify": 0
},
"confidence": 9,
"exclusion_rule": 3,
"refute_reasons": [
"intentional_behavior"
],
"first_links": [
"bee-harness/src/episode.rs:597",
"bee-harness/src/batch.rs:145"
],
"rationale": "Skill directories are deliberately authorized as readable from trusted operator-declared skill roots (bee-harness/src/episode.rs:745-754; bee-harness/src/scenario.rs:70-79). The most-specific rule behavior is intentional, and malicious skill frontmatter cannot select a different directory."
}
{"id":"f009","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":10.0,"exclusion_rule":null,"refute_reasons":[],"first_links":["crates/ebpf/src/main.rs:260"],"rationale":"The shared matcher normalizes root and trailing slashes at crates/common/src/matcher.rs:8-25, while crates/ebpf/src/main.rs:363-379 compares raw rule bytes and requires another separator. Compilation preserves these forms, so valid deny or read-only rules can silently miss descendants."}
20 changes: 1 addition & 19 deletions .triage-state/shard_f010.json
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@
{
"id": "f010",
"verdict": "false_positive",
"vote_breakdown": {
"true_positive": 0,
"false_positive": 3,
"cannot_verify": 0
},
"confidence": 8.7,
"exclusion_rule": 8,
"refute_reasons": [
"implausible_trigger"
],
"first_links": [
"bee-harness/src/mcp/bridge.rs:156",
"bee-harness/src/episode.rs:670"
],
"rationale": "The bridge can attach a token to HTTP (bee-harness/src/mcp/bridge.rs:326-345), but URL and token_env come only from trusted MCP configuration. No malicious model or MCP response can select the configured transport endpoint, so rule 8 applies."
}
{"id":"f010","verdict":"true_positive","vote_breakdown":{"true_positive":3,"false_positive":0,"cannot_verify":0},"confidence":9.7,"exclusion_rule":null,"refute_reasons":[],"first_links":["crates/userspace/src/spawn.rs:93"],"rationale":"Every model tool reaches pre_exec_hardening through crates/userspace/src/spawn.rs:91-98, but crates/userspace/src/hardening.rs:29-32 only changes dump settings. No UID/GID/capability drop or no_new_privs exists, and the privileged-image check covers only the initial executable."}
18 changes: 0 additions & 18 deletions .triage-state/shard_f011.json

This file was deleted.

Loading
Loading