Files
cleveragents-core/features/tui_shell_danger_detection.feature
freemo 5c49b2134b
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 15s
CI / helm (pull_request) Successful in 23s
CI / lint (pull_request) Successful in 3m16s
CI / quality (pull_request) Successful in 3m40s
CI / security (pull_request) Successful in 4m3s
CI / typecheck (pull_request) Successful in 4m11s
CI / unit_tests (pull_request) Successful in 9m21s
CI / docker (pull_request) Successful in 1m37s
CI / e2e_tests (pull_request) Failing after 13m4s
CI / coverage (pull_request) Successful in 12m28s
CI / integration_tests (pull_request) Successful in 24m23s
CI / status-check (pull_request) Failing after 3s
CI / benchmark-regression (pull_request) Successful in 55m11s
feat(tui): implement shell danger detection patterns
Implement dangerous shell pattern detection with configurable pattern
registry, danger level classification, and user warning system.

- Domain: ShellDangerLevel enum (LOW, MEDIUM, HIGH, CRITICAL)
- Domain: DangerousPattern value object with regex matching
- Domain: DangerousCommandWarning value object
- Domain: DangerousPatternDetector with configurable pattern registry
- Application: ShellSafetyService with warn_callback and block_level
- Default patterns: rm -rf, fork bomb, dd if=, mkfs, chmod 777,
  sudo rm, wget/curl piped to sh/bash, git push --force
- BDD tests covering all pattern categories, safe commands,
  registry management, and service behavior

ISSUES CLOSED: #1003
2026-04-02 20:48:33 +00:00

237 lines
11 KiB
Gherkin

Feature: TUI Shell Danger Detection
As a TUI user
I want dangerous shell commands to be detected and warned about
So that I can avoid accidentally running destructive commands
Background:
Given the shell safety module is imported
# ── Danger level enum ────────────────────────────────────────────────────
Scenario: ShellDangerLevel enum has four levels
Then the ShellDangerLevel enum should have levels LOW MEDIUM HIGH CRITICAL
Scenario: ShellDangerLevel levels are ordered by severity
Then LOW should be less severe than MEDIUM
And MEDIUM should be less severe than HIGH
And HIGH should be less severe than CRITICAL
# ── DangerousPattern value object ────────────────────────────────────────
Scenario: DangerousPattern matches a dangerous command
Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level
When I check if "rm -rf /" matches the pattern
Then the pattern should match
Scenario: DangerousPattern does not match a safe command
Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level
When I check if "ls -la" matches the pattern
Then the pattern should not match
Scenario: DangerousPattern is case-insensitive by default
Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level
When I check if "RM -RF /" matches the pattern
Then the pattern should match
# ── DangerousCommandWarning value object ─────────────────────────────────
Scenario: DangerousCommandWarning is created from a pattern
Given a DangerousPattern named "rm_root" with pattern "rm -rf /" at CRITICAL level
When I create a warning for command "rm -rf /" from the pattern
Then the warning command should be "rm -rf /"
And the warning danger level should be CRITICAL
And the warning message should contain "Critical"
And the warning message should contain "Dangerous command detected"
Scenario: DangerousCommandWarning message includes pattern description
Given a DangerousPattern named "fork_bomb" with pattern ":(){" at CRITICAL level and description "Fork bomb"
When I create a warning for command ":(){ :|:& };:" from the pattern
Then the warning message should contain "Fork bomb"
# ── DangerousPatternDetector ─────────────────────────────────────────────
Scenario: Detector uses default patterns when none provided
Given a DangerousPatternDetector with default patterns
Then the detector should have patterns registered
Scenario: Detector detects rm -rf root as CRITICAL
Given a DangerousPatternDetector with default patterns
When I check the command "rm -rf /"
Then the command should be detected as dangerous
And the max danger level should be CRITICAL
Scenario: Detector detects rm -rf wildcard as CRITICAL
Given a DangerousPatternDetector with default patterns
When I check the command "rm -rf /*"
Then the command should be detected as dangerous
And the max danger level should be CRITICAL
Scenario: Detector detects fork bomb as CRITICAL
Given a DangerousPatternDetector with default patterns
When I check the command ":(){ :|:& };:"
Then the command should be detected as dangerous
And the max danger level should be CRITICAL
Scenario: Detector detects dd if= as HIGH
Given a DangerousPatternDetector with default patterns
When I check the command "dd if=/dev/zero of=/dev/sda"
Then the command should be detected as dangerous
And the max danger level should be HIGH
Scenario: Detector detects mkfs as HIGH
Given a DangerousPatternDetector with default patterns
When I check the command "mkfs.ext4 /dev/sdb1"
Then the command should be detected as dangerous
And the max danger level should be HIGH
Scenario: Detector detects chmod 777 as MEDIUM
Given a DangerousPatternDetector with default patterns
When I check the command "chmod 777 /etc/passwd"
Then the command should be detected as dangerous
And the max danger level should be MEDIUM
Scenario: Detector detects sudo rm as MEDIUM
Given a DangerousPatternDetector with default patterns
When I check the command "sudo rm file.txt"
Then the command should be detected as dangerous
And the max danger level should be MEDIUM
Scenario: Detector detects wget piped to sh as MEDIUM
Given a DangerousPatternDetector with default patterns
When I check the command "wget http://example.com/install.sh | sh"
Then the command should be detected as dangerous
And the max danger level should be MEDIUM
Scenario: Detector detects curl piped to sh as MEDIUM
Given a DangerousPatternDetector with default patterns
When I check the command "curl http://example.com/install.sh | sh"
Then the command should be detected as dangerous
And the max danger level should be MEDIUM
Scenario: Detector detects curl piped to bash as MEDIUM
Given a DangerousPatternDetector with default patterns
When I check the command "curl https://get.example.com | bash"
Then the command should be detected as dangerous
And the max danger level should be MEDIUM
Scenario: Detector detects git push force as LOW
Given a DangerousPatternDetector with default patterns
When I check the command "git push --force origin main"
Then the command should be detected as dangerous
And the max danger level should be LOW
Scenario: Safe commands pass through without warnings
Given a DangerousPatternDetector with default patterns
When I check the command "ls -la"
Then the command should not be detected as dangerous
Scenario: Safe commands - echo passes through
Given a DangerousPatternDetector with default patterns
When I check the command "echo hello world"
Then the command should not be detected as dangerous
Scenario: Safe commands - git status passes through
Given a DangerousPatternDetector with default patterns
When I check the command "git status"
Then the command should not be detected as dangerous
Scenario: Safe commands - python script passes through
Given a DangerousPatternDetector with default patterns
When I check the command "python script.py"
Then the command should not be detected as dangerous
Scenario: check_first returns the first matching warning
Given a DangerousPatternDetector with default patterns
When I call check_first on "rm -rf /"
Then check_first should return a warning
And the first warning danger level should be CRITICAL
Scenario: check_first returns None for safe commands
Given a DangerousPatternDetector with default patterns
When I call check_first on "ls -la"
Then check_first should return None
Scenario: check returns all matching warnings
Given a DangerousPatternDetector with default patterns
When I call check on "rm -rf /"
Then check should return at least one warning
Scenario: Pattern registry is configurable - add pattern
Given a DangerousPatternDetector with default patterns
When I add a custom pattern named "custom_test" with pattern "evil_command" at HIGH level
And I check the command "evil_command --destroy"
Then the command should be detected as dangerous
Scenario: Pattern registry is configurable - remove pattern
Given a DangerousPatternDetector with default patterns
When I remove the pattern named "git_push_force"
And I check the command "git push --force origin main"
Then the command should not be detected as dangerous
Scenario: Pattern registry is configurable - replace patterns
Given a DangerousPatternDetector with default patterns
When I replace all patterns with a single pattern named "only_one" matching "special_cmd" at LOW level
And I check the command "rm -rf /"
Then the command should not be detected as dangerous
When I check the command "special_cmd"
Then the command should be detected as dangerous
Scenario: Detector patterns property returns current registry
Given a DangerousPatternDetector with default patterns
Then the detector patterns property should return a tuple
# ── ShellSafetyService ───────────────────────────────────────────────────
Scenario: ShellSafetyService allows safe commands
Given a ShellSafetyService with default settings
When I check the safety of command "ls -la"
Then the safety check result should be allowed
And the safety check warning should be None
Scenario: ShellSafetyService blocks dangerous commands above block level
Given a ShellSafetyService with default settings
When I check the safety of command "rm -rf /"
Then the safety check result should be blocked
And the safety check warning should not be None
Scenario: ShellSafetyService uses warn_callback when provided
Given a ShellSafetyService with a warn_callback that returns True
When I check the safety of command "rm -rf /"
Then the safety check result should be allowed
And the warn_callback should have been called
Scenario: ShellSafetyService blocks when warn_callback returns False
Given a ShellSafetyService with a warn_callback that returns False
When I check the safety of command "rm -rf /"
Then the safety check result should be blocked
And the warn_callback should have been called
Scenario: ShellSafetyService is_safe returns True for safe commands
Given a ShellSafetyService with default settings
When I call is_safe on "echo hello"
Then is_safe should return True
Scenario: ShellSafetyService is_safe returns False for dangerous commands
Given a ShellSafetyService with default settings
When I call is_safe on "rm -rf /"
Then is_safe should return False
Scenario: ShellSafetyService exposes detector property
Given a ShellSafetyService with default settings
Then the service detector property should be a DangerousPatternDetector
Scenario: ShellSafetyService exposes block_level property
Given a ShellSafetyService with default settings
Then the service block_level should be MEDIUM
Scenario: ShellSafetyService accepts extra_patterns
Given a ShellSafetyService with an extra pattern "custom_danger" matching "forbidden_cmd" at HIGH level
When I check the safety of command "forbidden_cmd --run"
Then the safety check result should be blocked
Scenario: SafetyCheckResult repr includes command and allowed status
Given a ShellSafetyService with default settings
When I check the safety of command "ls -la"
Then the safety check result repr should contain "ls -la"
And the safety check result repr should contain "allowed=True"