Skip to content

Apply security-hardening patch set - #22

Closed
rdasilveiracabral wants to merge 6 commits into
mainfrom
cursor/apply-security-hardening-patches-44e0
Closed

Apply security-hardening patch set#22
rdasilveiracabral wants to merge 6 commits into
mainfrom
cursor/apply-security-hardening-patches-44e0

Conversation

@rdasilveiracabral

@rdasilveiracabral rdasilveiracabral commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Applies the uploaded security-hardening patch series (see its README) and aligns the test suite with the resulting behavior change. Each numbered patch is one commit; the changes are disjoint by file.

  1. Playground model boundary (unifiedllm/registry.py, viewer/trace_routes.py) — validates api_key_env names, adds an allowed_env_vars allow-list to resolve_api_key_from_config, and constrains browser-supplied playground models to endpoint/api_key_env pairs already declared server-side.
  2. Viewer access + ingest hardening (nooa-cli .../start_dev.py, viewer/main.py) — default bind moves to 127.0.0.1, optional bearer-token auth (NOOA_VIEWER_AUTH_TOKEN) gated by ensure_viewer_bind_is_safe, and bounded OTLP/journal ingestion (max body sizes, bounded queue with 503 backpressure, journal item cap).
  3. Code-execution sandbox hardening (config/strategy_config.py, runtime/actor.py, runtime/restrictions.py, runtime/sandbox/executor.py, runtime/sandbox/worker.py, strategies/codeact.py) — makes sandbox the CodeAct default with a cell_timeout of 30s, populates DEFAULT_RESTRICTED_IMPORTS with host-capability modules, scrubs the worker environment of parent secrets, syncs per-cell namespace/Out into the worker, and enforces agentdoc visibility on every broker path.

Application notes

  • Patch 1 applied cleanly. Patches 2 and 3 had context drift; several hunks were applied with fuzz and the rest reconciled by hand (notably session state now crosses into the sandbox via execute_code(..., builtins={**builtins, **session.session_locals})run_cell(..., builtins=...) → the new _namespace_updates worker sync). Fuzz mis-placed two executor.py/actor.py hunks, which I reconstructed by hand.
  • ruff check and ruff format --check pass repo-wide.

Test alignment

uv run pytest -m "not integration and not stress"6528 passed, 4 skipped, 0 failed. The sandbox-default flip initially broke 20 tests; those are now addressed in two commits:

  • Default-value assertions (4) updated to the new spec: CodeActConfig defaults (execution_backend="sandbox", cell_timeout=30.0), and the populated DEFAULT_RESTRICTED_IMPORTS constant.
  • In-process-semantics tests (16) pinned to execution_backend="inprocess". These validate in-process internals — session_locals write-back, FakeLLMClient call counting, in-cell nested/standalone generation, current_call, and ATIF trajectory structure — which differ under the forked sandbox worker (a FakeLLMClient and parent-side locals don't cross the fork). Pinning preserves their intent; sandbox-mode coverage for these flows is a follow-up.

No source files were changed for the test alignment — only tests.

Behavior notes for reviewers

  • This is a real behavior change, not just defaults. Any caller using CodeActConfig() now runs cells in a forked, env-scrubbed worker with a 30s hard per-cell timeout and broker-visibility enforcement.
  • QuickStart verified working under the new default with a live LLM: 01_first_generation_method.py and 06_tracing.py both produced correct output.
  • Bench agent inherits the new default. BenchAgent._solve_task sets CodeActConfig(max_iterations=300, ...) without execution_backend, so it now runs in sandbox. It mostly uses brokered self.shell/self.repo (still execute in the parent), but the worker env scrub, host-import restrictions, and 30s per-cell timeout are behavioral risks that were not validated against a live benchmark — consider pinning it to inprocess or giving it an explicit sandbox config.
  • DEFAULT_RESTRICTED_IMPORTS is currently inert by default. RestrictionsConfig.restricted_imports still defaults to frozenset() and nothing wires the populated constant in (it only applies via set_restricted_imports(...)), so the patch's "block host imports by default" effect is not actually active as written against main. If that effect is intended, the field default needs to reference DEFAULT_RESTRICTED_IMPORTS (and expect further test fallout). Flagging rather than changing it unilaterally.

Verification

  • uv run ruff check . → all checks passed.
  • uv run ruff format --check . → clean (871 files).
  • uv run pytest -m "not integration and not stress" → 6528 passed, 4 skipped.
Open in Web Open in Cursor 

cursoragent and others added 6 commits July 25, 2026 16:52
Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
…rker env, enforce broker visibility

Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
…l_timeout, and populated DEFAULT_RESTRICTED_IMPORTS

Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
These tests exercise in-process execution internals (session_locals write-back, FakeLLMClient call counting, in-cell nested/standalone generation, current_call, ATIF trajectory structure) that differ under the forked sandbox worker. Pin them to the in-process backend so they keep validating that path; sandbox-mode coverage for these flows is tracked separately.

Co-authored-by: Ricardo Silveira Cabral <rdasilveiracabral@users.noreply.github.com>
@rdasilveiracabral

Copy link
Copy Markdown
Collaborator Author

Closing as stale — superseded by the security hardening work that was merged separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants