test(permission): lock in elf safety-pattern inheritance
Audit finding H2 hypothesised that spawn_elfs/agent's safetyCheck exemption could be reached as a bypass route if the spawned elf failed to enforce the same patterns. Verified by inspection that: 1. WithDenyPrompt copies safetyDenyPatterns into the elf checker. 2. Check() runs safetyCheck (Step 2) before ModeBypass (Step 3), so bypass cannot skip safety. 3. main.go always passes the parent permChecker to the elf Manager. H2 is not exploitable in current code. This test pins the contract so future refactors of WithDenyPrompt cannot silently drop pattern inheritance.
This commit is contained in:
@@ -202,6 +202,35 @@ func TestChecker_SafetyCheck(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestChecker_ElfInheritsSafetyPatterns(t *testing.T) {
|
||||
// Audit H2: spawn_elfs/agent are exempt from safetyCheck at the orchestration
|
||||
// layer, with the rationale that the spawned elf will be checked when it
|
||||
// actually accesses files. That contract requires the elf checker (built via
|
||||
// WithDenyPrompt) to inherit the parent's safetyDenyPatterns AND for those
|
||||
// patterns to still fire even in ModeBypass.
|
||||
parent := NewChecker(ModeBypass, nil, nil)
|
||||
elfChecker := parent.WithDenyPrompt()
|
||||
|
||||
safetyCases := []struct {
|
||||
name string
|
||||
toolName string
|
||||
args string
|
||||
}{
|
||||
{"env file", "fs.read", `{"path":".env"}`},
|
||||
{"ssh key", "fs.read", `{"path":"id_rsa"}`},
|
||||
{"aws creds", "fs.read", `{"path":".aws/credentials"}`},
|
||||
{"bash on env", "bash", `{"command":"cat .env"}`},
|
||||
}
|
||||
for _, tt := range safetyCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := elfChecker.Check(context.Background(), ToolInfo{Name: tt.toolName}, json.RawMessage(tt.args))
|
||||
if !errors.Is(err, ErrDenied) {
|
||||
t.Errorf("elf checker must still block %s on %s, got: %v", tt.args, tt.toolName, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestChecker_SafetyCheck_OrchestrationToolsExempt(t *testing.T) {
|
||||
// spawn_elfs and agent carry elf PROMPT TEXT as args — arbitrary instruction
|
||||
// text that may legitimately mention .env, credentials, etc.
|
||||
|
||||
Reference in New Issue
Block a user