fix(security): 0.40.3 deferred hardening - out-of-process code, SSRF pinning, MCP scoping#274
Closed
gizmax wants to merge 1 commit into
Closed
fix(security): 0.40.3 deferred hardening - out-of-process code, SSRF pinning, MCP scoping#274gizmax wants to merge 1 commit into
gizmax wants to merge 1 commit into
Conversation
gizmax
force-pushed
the
fix/audit-deferred-hardening
branch
2 times, most recently
from
July 11, 2026 21:46
b5ad2dc to
9aef520
Compare
…pinning, MCP scoping Finishes the three deferred items from the 0.40.2 audit sweep. - Code steps run out-of-process by default (CODE_STEPS_OUT_OF_PROCESS): a separate Python subprocess with a secret-free env and POSIX CPU/AS limits, really killed on timeout. Same AST/blocklist/helpers reused in the child. Infra failures fall back to the in-process path. - HTTP steps pin the validated IP at connect time via a custom httpx transport that preserves Host + TLS SNI, closing the DNS-rebind TOCTOU. Mocked and non-resolvable hosts unaffected. - Memory MCP enforces MEMORY_MCP_SCOPE_PREFIX on every tool call; forget requires and validates the owning user_id against the prefix.
gizmax
force-pushed
the
fix/audit-deferred-hardening
branch
from
July 11, 2026 22:05
9aef520 to
62b9d63
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #273 (0.40.2). Finishes the three harder, previously-deferred audit items. Base is the 0.40.2 branch so this diff shows only the deferred work; merge after #273.
What's in this PR
python -m sandcastle.engine.code_subprocess_runner) with a secret-free env and POSIX CPU/address-space limits; the same AST validator, blocklist, and secret-free helpers are re-run in the child (imported, not forked). The child is really killed on timeout - the in-process thread path could not be. Gated byCODE_STEPS_OUT_OF_PROCESS(default true); spawn/serialization failures fall back to in-process so a step is never lost. Parent still validates before spawning.httpx.AsyncHTTPTransportdials the validated IP while preservingHost+ TLS SNI. Closes the DNS-rebind TOCTOU.gaierrorstill swallowed and no pin applied then, so mocked/non-resolvable test hosts behave as before.MEMORY_MCP_SCOPE_PREFIXenforced onadd/search/list_memories/forget;forgetrequires + validates the owninguser_id. Unset = today's behavior.Testing (reviewed line-by-line by lead + independently re-run)
test_code_subprocess_runner,test_http_ssrf_pinning,test_memory_mcp_server,test_security_pentest,test_code_steps_admin_gate,test_step_types-> 325 passed.Notes / residual limitations (reviewed, acceptable)
CODE_STEPS_OUT_OF_PROCESS=false.forget: mem0 deletes by id with no owner-by-id lookup, soforgetvalidates the supplieduser_idis in-prefix but cannot cross-check that thememory_idtruly belongs to it. Safe for per-tenant (one prefix per token) deployments; a stronger check needs an owner-resolve primitive inmemory.py.