Skip to content

[ai] fix(security): serialize Mojo shared-memory payloads as JSON, not pickle - #1832

Draft
github-actions[bot] wants to merge 1 commit into
mainfrom
pr-iteration/fix/mojo-shared-memory-pickle-json
Draft

[ai] fix(security): serialize Mojo shared-memory payloads as JSON, not pickle#1832
github-actions[bot] wants to merge 1 commit into
mainfrom
pr-iteration/fix/mojo-shared-memory-pickle-json

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Canonical issue

Closes #913. Supersedes stale draft PR #1596 (same intent, but that branch carries ~8,800 unrelated lines of pre-rewrite main drift and was never verified in CI — the author's own PR description notes "the session ended before tests could be run").

Problem

src/agents/unified/mcp_a2a_mojo_integration.py used pickle.dumps(message) to serialize UnifiedMessage into a cross-process shared-memory segment (MojoTransportLayer._shared_memory_send). A receiver that later pickle.loads-decodes bytes read from shared memory can be forced into arbitrary code execution by a malicious or compromised writer on the other end of that IPC channel — the same RCE pattern already remediated for the Redis cache path elsewhere in this repo (see intelligent_cache.py, "pickle removed for security").

Fix

  • Removed the pickle import.
  • _shared_memory_send now builds a plain JSON payload from the existing to_dict() methods already implemented on UnifiedMessage's A2AMessage and MCPContext members (plus the transport-strategy enum value and scalar fields), then json.dumps(...).encode("utf-8").
  • Scope kept minimal: no behavior change to transport selection, latency stats, cleanup, or any other transport method (_zero_copy_send, _pipe_send, _handle_passing_send).

Verification

  • PYTHONPATH=src python -m pytest tests/unit/test_security_fixes.py -v --no-cov21 passed (19 pre-existing + 2 new).
  • PYTHONPATH=src python -m pytest tests/unit/ -k "mcp_a2a or mojo or a2a or security_fixes" --no-cov -q50 passed, 8184 deselected.
  • python -m py_compile src/agents/unified/mcp_a2a_mojo_integration.py tests/unit/test_security_fixes.py → OK.
  • Manual smoke: constructed a UnifiedMessage and called _shared_memory_send directly — result payload is valid json.loads-parseable UTF-8 with no pickle opcodes, confirmed by the new regression test TestMojoSharedMemoryPickleFix::test_shared_memory_send_serializes_as_json.
  • ruff check on the touched region shows no new findings (remaining lint hits in the same file are pre-existing E402s unrelated to this change).

New test coverage

Added TestMojoSharedMemoryPickleFix to tests/unit/test_security_fixes.py:

  1. Asserts the module source no longer contains import pickle / pickle.dumps / pickle.loads.
  2. Round-trips a real UnifiedMessage through _shared_memory_send and asserts the shared-memory bytes are valid JSON containing the expected fields, then cleans up the shared-memory block.

Repo-context notes

This run of the pr-iteration-loop selected this checkpoint under priority 2 (open PRs unresolved >7 days) after verifying that the workflow-run candidates supplied in pr-iteration-loop-context.json (Security Scan / PR Governance / API cost PostgreSQL / CI failures on cursor/videopack-paste-url-fee2 and cursor/public-video-pack-emit-fb40) were all tied to branches already merged/closed via PR #1609 on 2026-09-02, with zero reproducible failures remaining on current main (gh run list --branch main shows 100% success in the trailing window). Full triage evidence, the staleness chart, and the pattern recommendation are recorded in the workflow's cache-memory for future runs.

Recommended automation pattern for this class of work: Continuous AI — a bounded, LLM-verifiable code fix discovered by triaging existing CI/PR/issue signal through standard platform tooling (gh, pytest, ruff), not a real-time multiplayer task (Chopin), a simple fixed-goal loop with no repo-signal triage (Autoloop), or bespoke natural-language GitHub Actions authoring (Agentic Workflows).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Generated by pr-iteration-loop · copilot · auto · 185.5 AIC · ⌖ 20.4 AIC · ⊞ 12.1K ·

  • expires on Sep 16, 2026, 7:01 PM UTC

Replace pickle.dumps in MojoTransportLayer._shared_memory_send with a JSON
payload built from the existing UnifiedMessage/A2AMessage/MCPContext
to_dict() methods. A receiver that unpickles data read from a
cross-process shared-memory segment can be forced into arbitrary code
execution by a malicious or compromised writer; JSON has no executable
payload. Adds a regression test asserting the module no longer imports
pickle and that the shared-memory write is valid JSON.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
v0-uvai Ready Ready Preview, v0 Sep 9, 2026 7:02pm UTC

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Execution: sanitize v1 router log inputs (CWE-117) (PR #810)

0 participants