Skip to content
Open
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
3 changes: 2 additions & 1 deletion openjiuwen/harness/deep_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ def _queue_pending_rails(self, config: DeepAgentConfig) -> None:
if config.enable_task_loop:
self._pending_rails.append(TaskCompletionRail())

if isinstance(config.permissions, dict) and config.permissions.get("enabled"):
# 始终交给 factory:旧 enabled=false 会迁移为 mode=full_access 并挂载权限轨
if isinstance(config.permissions, dict):
ws_root = None
if config.workspace is not None:
ws_root = Path(config.workspace.root_path).resolve()
Expand Down
376 changes: 305 additions & 71 deletions openjiuwen/harness/rails/security/tool_security_rail.py

Large diffs are not rendered by default.

296 changes: 257 additions & 39 deletions openjiuwen/harness/resources/builtin_rules.yaml
Original file line number Diff line number Diff line change
@@ -1,84 +1,302 @@

# Built-in parameter-level rules for tiered_policy (shell / path guardrails).
# Built-in parameter-level rules for tiered_policy (shell guardrails).
#
# 分层策略仅加载本包内文件;覆盖规则请改主配置 ``permissions.rules`` 等,勿依赖用户目录同名 YAML
# 分层策略仅加载本包内文件;覆盖规则请改主配置 ``permissions.rules`` 等。
#
# This file stores built-in parameter-level rules in the shell guardrail
# design format. These rules are intended to be merged into the built-in
# guardrail layer before user-defined permissions.
# 平台(platforms,可省略 = all):
# - all:当前 OS 都会加载(含 Windows 上的 Git Bash / POSIX 工具)
# - unix:仅 Linux / macOS
# - windows:仅 Windows 原生命令
#
# Severity mapping is owned by the permissions engine:
# - LOW / MEDIUM / HIGH / CRITICAL are risk labels, not direct decisions.
# - In normal mode, HIGH and CRITICAL typically require confirmation.
# - In strict mode, CRITICAL should be denied.
# 分级(P1):
# - action: deny → 硬 Deny,三模式永远拒绝,不可 HITL 放宽
# - severity: CRITICAL → FA/Auto 为 ASK;Strict 可 DENY(severity_map)
# - severity: HIGH → ASK(控制误报)
#
# 路径内置底线在 ``sensitive_paths``(file_guard),不混入下方 ``rules``。

rules:
- id: shell_fs_recursive_or_forced_delete
description: "递归、强制或批量删除关键路径,可能造成不可恢复的数据破坏"
tools: [bash, mcp_exec_command, create_terminal]
# ---------- 硬 Deny ----------
- id: shell_rm_root_hard_deny
platforms: [all]
description: "删除根目录或其直接通配,属于灾难级破坏"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((rm\s+[^;&|]*(-[A-Za-z]*[rR][A-Za-z]*[fF]|-[A-Za-z]*[fF][A-Za-z]*[rR]|--recursive|--force)[^;&|]*(/[^;&|\s]*|\*|~[^;&|\s]*|\$HOME[^;&|\s]*|\.{1,2}(/[^;&|\s]*)?)(\s|$))|(find\s+[^;&|]*\s-delete\b)|(shred\b)|(del\s+[^;&|]*/[A-Za-z]*[fqs][A-Za-z]*)|(rd\s+[^;&|]*/s\b[^;&|]*/q\b))'
severity: CRITICAL
pattern: 're:(?i)(^|[\s;&|()])rm\s+(-[A-Za-z]*[rR][A-Za-z]*[fF]|-[A-Za-z]*[fF][A-Za-z]*[rR]|--recursive|--force)\s+(/|/\*)(\s|$)'
action: deny

- id: shell_disk_partition_or_raw_device_write
- id: shell_disk_partition_or_raw_device_write_unix
platforms: [unix]
description: "格式化、分区或直接写入块设备,可能破坏磁盘和文件系统"
tools: [bash, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((mkfs(\.[A-Za-z0-9_]+)?|mke2fs|fdisk|parted|diskpart|format)\b|(dd\b[^;&|]*(\bof=/dev/|\\\\\.\\PhysicalDrive))|(>\s*/dev/(sd[a-z][0-9]*|vd[a-z][0-9]*|xvd[a-z][0-9]*|nvme[0-9]+n[0-9]+(p[0-9]+)?|disk[0-9]+)))'
pattern: 're:(?i)(^|[\s;&|()])((mkfs(\.[A-Za-z0-9_]+)?|mke2fs|fdisk|parted)\b|(dd\b[^;&|]*(\bof=/dev/))|(>\s*/dev/(sd[a-z][0-9]*|vd[a-z][0-9]*|xvd[a-z][0-9]*|nvme[0-9]+n[0-9]+(p[0-9]+)?|disk[0-9]+)))'
action: deny

- id: shell_disk_partition_or_raw_device_write_win
platforms: [windows]
description: "格式化、分区或直接写入物理磁盘,可能破坏磁盘和文件系统"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((diskpart|format)\b|(dd\b[^;&|]*\\\\\.\\PhysicalDrive))'
action: deny

- id: shell_fork_bomb_or_resource_abuse
platforms: [all]
description: "fork bomb、解除进程限制或批量终止关键进程"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(:\s*\(\s*\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:|(^|[\s;&|()])kill\s+-9\s+(-1|1)\b|(^|[\s;&|()])ulimit\s+-u\s+unlimited\b)'
action: deny

- id: shell_system_shutdown_or_reboot
platforms: [all]
description: "关机、重启或切换到关机/重启运行级别,属于明显破坏系统可用性的行为"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((shutdown|reboot|halt|poweroff)\b|(init|telinit)\s+(0|6)\b)'
action: deny

# ---------- CRITICAL → ASK(Strict 可 DENY)----------
- id: shell_fs_recursive_or_forced_delete
platforms: [all]
description: "递归或强制删除(非根目标);需确认,避免工作区清理被硬拒"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((rm\s+[^;&|]*(-[A-Za-z]*[rR][A-Za-z]*[fF]|-[A-Za-z]*[fF][A-Za-z]*[rR]|--recursive|--force)\b)|(find\s+[^;&|]*\s-delete\b)|(shred\b))'
severity: CRITICAL

- id: shell_fs_recursive_or_forced_delete_win
platforms: [windows]
description: "Windows 递归或强制删除(del / rd)"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((del\s+[^;&|]*/[A-Za-z]*[fqs][A-Za-z]*)|(rd\s+[^;&|]*/s\b[^;&|]*/q\b))'
severity: CRITICAL

- id: shell_download_and_execute
description: "从网络下载内容后直接交给 shell、PowerShell 或动态执行器执行"
tools: [bash, mcp_exec_command, create_terminal]
platforms: [all]
description: "从网络下载内容后直接交给 shell 或动态执行器执行"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])(((curl|wget|fetch|ftp)\b[^;&]*\|\s*(bash|sh|zsh|dash|ash|source)\b)|((bash|sh|zsh|pwsh|powershell)\b[^;&|]*<\s*<\s*\(?\s*(curl|wget)\b))'
severity: CRITICAL

- id: shell_download_and_execute_win
platforms: [windows]
description: "从网络下载内容后交给 PowerShell 动态执行"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])(((curl|wget|fetch|ftp)\b[^;&]*\|\s*(bash|sh|zsh|dash|ash|source)\b)|(iwr|irm|Invoke-WebRequest|Invoke-RestMethod)\b[^;&|]*\|\s*(iex|Invoke-Expression)\b|((bash|sh|zsh|pwsh|powershell)\b[^;&|]*<\s*<\s*\(?\s*(curl|wget)\b))'
pattern: 're:(?i)(^|[\s;&|()])(iwr|irm|Invoke-WebRequest|Invoke-RestMethod)\b[^;&|]*\|\s*(iex|Invoke-Expression)\b'
severity: CRITICAL

- id: shell_obfuscated_or_dynamic_execution
description: "编码载荷、解码后执行、eval/iex 或内联解释器执行,命令难以审计"
tools: [bash, mcp_exec_command, create_terminal]
platforms: [all]
description: "编码载荷、解码后执行、eval 或内联解释器执行,命令难以审计"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((base64\s+(-d|--decode)\b[^;&|]*\|\s*(bash|sh|zsh|dash|ash)\b)|(eval\s+[`$])|((python3?|perl|ruby|node)\s+(-c|-e)\b[^;&|]*(socket|subprocess|exec|eval|child_process)))'
severity: CRITICAL

- id: shell_obfuscated_or_dynamic_execution_win
platforms: [windows]
description: "PowerShell 编码载荷、certutil 解码或 iex 动态执行"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((base64\s+(-d|--decode)\b[^;&|]*\|\s*(bash|sh|zsh|dash|ash)\b)|(certutil\s+-decode\b)|(-EncodedCommand\b|-[Ee]nc\b)|(\[Convert\]::FromBase64String\()|(eval\s+[`$])|(\b(iex|Invoke-Expression)\b)|((python3?|perl|ruby|node)\s+(-c|-e)\b[^;&|]*(socket|subprocess|exec|eval|child_process)))'
pattern: 're:(?i)(^|[\s;&|()])((certutil\s+-decode\b)|(-EncodedCommand\b|-[Ee]nc\b)|(\[Convert\]::FromBase64String\()|(\b(iex|Invoke-Expression)\b))'
severity: CRITICAL

- id: shell_reverse_shell_or_bind_shell
platforms: [all]
description: "反向 shell、绑定 shell 或可疑网络执行通道"
tools: [bash, mcp_exec_command, create_terminal]
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(/dev/(tcp|udp)/|(^|[\s;&|()])(nc|ncat)\b[^;&|]*\s(-e|--exec)\s|\bsocat\b[^;&|]*(EXEC:|SYSTEM:|PTY)|\bbash\s+-i\b[^;&|]*/dev/tcp/|\bpython3?\b[^;&|]*(socket|pty\.spawn|subprocess)|\bperl\b[^;&|]*Socket)'
severity: CRITICAL

- id: shell_privilege_escalation
description: "通过 sudo、su、doas、pkexec、runas 或管理员启动方式提升权限"
platforms: [unix]
description: "通过 sudo、su、doas、pkexec 提升权限"
tools: [bash, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((sudo|doas|pkexec)\s+|su\s+(-|root|\w)|runas\b|Start-Process\b[^;&|]*-Verb\s+RunAs\b|psexec\b|schtasks\b[^;&|]*/ru\s+SYSTEM\b)'
pattern: 're:(?i)(^|[\s;&|()])((sudo|doas|pkexec)\s+|su\s+(-|root|\w))'
severity: CRITICAL

- id: shell_data_exfiltration
description: "通过 HTTP、scp、rsync、ftp、nc 等方式上传本地文件或命令输出"
tools: [bash, mcp_exec_command, create_terminal]
- id: shell_privilege_escalation_win
platforms: [windows]
description: "通过 runas、管理员启动或 SYSTEM 计划任务提升权限"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])(((curl|wget|Invoke-WebRequest|iwr|Invoke-RestMethod|irm)\b[^;&|]*(--data|--data-binary|--upload-file|-d\b|-F\b|-T\b|POST|PUT))|(scp\b[^;&|]+\s+\S+:)|(rsync\b[^;&|]+\s+\S+:)|(sftp|ftp)\b|\bnc\b[^;&|]*\s(443|80|8080|53)\b)'
pattern: 're:(?i)(^|[\s;&|()])(runas\b|Start-Process\b[^;&|]*-Verb\s+RunAs\b|psexec\b|schtasks\b[^;&|]*/ru\s+SYSTEM\b)'
severity: CRITICAL

- id: shell_remote_execution_or_lateral_movement
description: "远程会话、远程进程创建或横向移动命令"
tools: [bash, mcp_exec_command, create_terminal]
platforms: [all]
description: "通过 ssh 远程执行命令"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((Invoke-Command|Enter-PSSession|New-PSSession)\b|winrs\b|wmic\b[^;&|]*process\s+call\s+create|psexec\b|ssh\b[^;&|]*\s\S+\s+["''][^"'']+["''])'
pattern: 're:(?i)(^|[\s;&|()])ssh\b[^;&|]*\s\S+\s+["''][^"'']+["'']'
severity: CRITICAL

- id: shell_fork_bomb_or_resource_abuse
description: "fork bomb、解除进程限制或批量终止关键进程"
tools: [bash, mcp_exec_command, create_terminal]
- id: shell_remote_execution_or_lateral_movement_win
platforms: [windows]
description: "Windows 远程会话、远程进程创建或横向移动命令"
tools: [powershell, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(:\s*\(\s*\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:|(^|[\s;&|()])kill\s+-9\s+(-1|1)\b|(^|[\s;&|()])ulimit\s+-u\s+unlimited\b)'
pattern: 're:(?i)(^|[\s;&|()])((Invoke-Command|Enter-PSSession|New-PSSession)\b|winrs\b|wmic\b[^;&|]*process\s+call\s+create|psexec\b)'
severity: CRITICAL

- id: shell_system_shutdown_or_reboot
description: "关机、重启或切换到关机/重启运行级别,属于明显破坏系统可用性的行为"
- id: shell_docker_privileged
platforms: [all]
description: "以特权模式运行容器,可突破隔离"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])docker\s+run\b[^;&|]*--privileged\b'
severity: CRITICAL

# ---------- HIGH → ASK ----------
- id: shell_data_exfiltration
platforms: [all]
description: "通过 HTTP、scp、rsync、ftp、nc 等方式上传本地文件或命令输出"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])(((curl|wget|Invoke-WebRequest|iwr|Invoke-RestMethod|irm)\b[^;&|]*(--data|--data-binary|--upload-file|-d\b|-F\b|-T\b|POST|PUT))|(scp\b[^;&|]+\s+\S+:)|(rsync\b[^;&|]+\s+\S+:)|(sftp|ftp)\b|\bnc\b[^;&|]*\s(443|80|8080|53)\b)'
severity: HIGH

- id: shell_chmod_world_writable
platforms: [all]
description: "递归放开写权限,扩大本地提权面"
tools: [bash, mcp_exec_command, create_terminal, powershell]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])chmod\s+(-R\s+)?([0-7]*7[0-7]{2}|a\+[rwx]*w|777)\b'
severity: HIGH

- id: shell_ld_preload
platforms: [unix]
description: "通过 LD_PRELOAD 注入动态库"
tools: [bash, mcp_exec_command, create_terminal]
match_type: command
pattern: 're:(?i)(^|[\s;&|()])((shutdown|reboot|halt|poweroff)\b|(init|telinit)\s+(0|6)\b)'
pattern: 're:(?i)(^|[\s;&|()])(export\s+)?LD_PRELOAD='
severity: HIGH

# 路径内置底线(file_guard):action 仅 ask|deny,注入时三轴同值;用户 YAML 不可放宽。
# 当前清单跨平台(~/ 由 Path.home() 展开);仅某一 OS 的路径再标 platforms。
sensitive_paths:
# ---- deny ----
- id: home_ssh
platforms: [all]
path: "~/.ssh/**"
match: glob
action: deny
- id: any_ssh
platforms: [all]
path: "**/.ssh/**"
match: glob
action: deny
- id: any_env
platforms: [all]
path: "**/.env*"
match: glob
action: deny
- id: any_id_rsa
platforms: [all]
path: "**/id_rsa"
match: glob
action: deny
- id: any_id_rsa_ext
platforms: [all]
path: "**/id_rsa.*"
match: glob
action: deny
- id: any_id_ed25519
platforms: [all]
path: "**/id_ed25519"
match: glob
action: deny
- id: any_id_ed25519_ext
platforms: [all]
path: "**/id_ed25519.*"
match: glob
action: deny
- id: any_pem
platforms: [all]
path: "**/*.pem"
match: glob
action: deny
- id: any_pfx
platforms: [all]
path: "**/*.pfx"
match: glob
action: deny
- id: any_key
platforms: [all]
path: "**/*.key"
match: glob
action: deny

# ---- ask ----
- id: home_aws
platforms: [all]
path: "~/.aws/**"
match: glob
action: ask
- id: home_kube_config
platforms: [all]
path: "~/.kube/config"
match: glob
action: ask
- id: home_docker_config
platforms: [all]
path: "~/.docker/config.json"
match: glob
action: ask
- id: home_docker_daemon
platforms: [all]
path: "~/.docker/daemon.json"
match: glob
action: ask
- id: home_netrc
platforms: [all]
path: "~/.netrc"
match: glob
action: ask
- id: home_npmrc
platforms: [all]
path: "~/.npmrc"
match: glob
action: ask
- id: home_pypirc
platforms: [all]
path: "~/.pypirc"
match: glob
action: ask
- id: home_gem_credentials
platforms: [all]
path: "~/.gem/credentials"
match: glob
action: ask
- id: home_gh_hosts
platforms: [all]
path: "~/.config/gh/hosts.yml"
match: glob
action: ask
- id: home_git_credentials
platforms: [all]
path: "~/.git-credentials"
match: glob
action: ask
- id: home_gcloud
platforms: [all]
path: "~/.config/gcloud/**"
match: glob
action: ask
- id: home_azure
platforms: [all]
path: "~/.azure/**"
match: glob
action: ask
- id: home_terraform_creds
platforms: [all]
path: "~/.terraform.d/credentials.tfrc.json"
match: glob
action: ask
Loading