test(agents): capture inline sandbox __import__ escape regression (#107) #110
No reviewers
Labels
No labels
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Bounty
$100
Bounty
$1000
Bounty
$10000
Bounty
$20
Bounty
$2000
Bounty
$250
Bounty
$50
Bounty
$500
Bounty
$5000
Bounty
$750
MoSCoW
Could have
MoSCoW
Must have
MoSCoW
Should have
Needs Feedback
Points
1
Points
13
Points
2
Points
21
Points
3
Points
34
Points
5
Points
55
Points
8
Points
88
Priority
Backlog
Priority
CI Blocker
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
State
Completed
State
Duplicate
State
In Progress
State
In Review
State
Paused
State
Unverified
State
Verified
State
Wont Do
Type
Automation
Type
Bug
Type
Discussion
Type
Documentation
Type
Epic
Type
Feature
Type
Legendary
Type
Refactor
Type
Support
Type
Task
Type
Testing
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Blocks
#108 TDD: Inline-code sandbox exposes __import__, letting code bypass the Restricted Built-ins set entirely (e.g. import os)
cleveragents/cleveractors-core
Reference
cleveragents/cleveractors-core!110
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "tdd/m1-inline-sandbox-import-restriction"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a failing-first Behave regression test proving issue #107:
ToolAgent._execute_python_code(cleveractors.agents.tool) builds the inline-code sandbox's__builtins__dict perdocs/index.md§13.2.1's "Restricted Built-ins for Inline Code" table, which lists a single module-shaped facility (json) and states that table is exhaustive. §13.2.3 additionally prohibits "dynamic import of modules other than those explicitly listed". Despite this,safe_globals["__builtins__"]["__import__"]is bound directly to the real, unrestricted__import__builtin, so inline code can writeimport osand reach exactly the filesystem/network/process facilities the standard was written to keep out.Two scenarios drive the two documented entry points that share
_execute_python_code— atype: toolagent's inlinecode:body, and theexec_python-gatedpython_execbuilt-in tool — through the publicToolAgent.process_message()API with code that doesimport os; result = os.getcwd(), and assert anExecutionErroris raised instead of the import succeeding. Today it isn't: both return the real working directory path.Both scenarios are tagged
@tdd_issue,@tdd_issue_107, and@tdd_expected_failper the TDD issue-capture workflow.The actual fix (a restricted
__import__shim permitting onlyjson) lands separately onbugfix/m1-inline-sandbox-import-restrictionper issue #107.Test plan
nox -s lintgreennox -s format -- --checkgreennox -s typecheckgreennox -s security_scangreennox -s dead_codegreennox -s unit_testsgreen — confirms both assertions fail viaAssertionErrorwithout the@tdd_expected_failtag (verified locally by temporarily removing it), andTddExpectedFailPolicyinverts them to a pass with the tag presentnox -s coverage_report— 96.7% (>= 96.5% threshold)nox -s integration_tests— greennox -s e2e_tests— greennox -s complexity,nox -s benchmark_regression— informational, unaffected by this test-only changeCloses #108
PR Review: !110 (Ticket #108)
Verdict: Approve
The PR correctly implements the TDD regression test for issue #107 as specified in #108. The two Behave scenarios cover both documented entry points into
ToolAgent._execute_python_code, carry the required@tdd_issue @tdd_issue_107 @tdd_expected_failtags, and rely onAssertionErrorso theTddExpectedFailPolicyinversion works as intended. No critical or major technical issues were found.Critical Issues
None
Major Issues
None
Minor Issues
noxfile.py:27setsCOVERAGE_THRESHOLD = 96.5, whileCONTRIBUTING.md§"Project-Specific Guidelines" and.gitea/workflows/ci.ymlstate the enforced coverage gate is 97%. The PR test plan reports 96.7% and passes noxfile.py's threshold, but this inherited project-level inconsistency could mask a real coverage regression. Recommend aligningnoxfile.pywith the documented 97% gate (separate from this PR, or clarify if 96.5% is intentional).Nits
features/inline_sandbox_import_restriction.feature:44,56only tests theimport osform. Other dynamic-import forms (e.g.,from os import getcwdor__import__('os')) share the same__import__bypass and could be added in the fix PR (#107) to harden the restriction.Summary
This is a clean, focused TDD capture PR. The scenarios correctly exercise the sandbox escape through both the
python_execbuilt-in tool and atype: toolinlinecode:body, and they will flip from inverted-fail to outright pass once the fix in #107 replaces the raw__import__reference. The code is statically typed, lint-clean, and follows the project's BDD/TDD conventions. Approving.timeoutargumenttimeoutargumentMinor issues number 1 - coverage, is not relevant, we have a noxfile threshold at 96.5% while having a 97% in the specification, but the 97% is the rounded value, which is also obtainable from a 96.5% real coverage.
bac4868abd35e9f22bdeAddressed Rui's Nit #1 directly on this branch (amended, not a separate PR): both scenarios are now Scenario Outlines exercising three dynamic-import forms that all resolve through the same unrestricted
__import__—import os,from os import getcwd, and__import__('os')— across both entry points (6 scenarios total). Verified locally that all fail viaAssertionErrorwithout@tdd_expected_failand pass via the inversion with it present (nox -s unit_tests -- features/inline_sandbox_import_restriction.feature).lint,typecheck,format --check,security_scan, anddead_codeall still green.Minor Issue #1 (coverage threshold) is not being changed here — per my earlier comment it's a pre-existing, repo-wide noxfile.py setting unrelated to this test-only PR; revisiting it would require raising overall project coverage separately and is out of scope for #108.
35e9f22bde543248ffd4