From af95f94db11ca91b8aecf3032b91ce976dcd10f7 Mon Sep 17 00:00:00 2001 From: Molecule AI Core-BE Date: Mon, 11 May 2026 07:07:30 +0000 Subject: [PATCH] =?UTF-8?q?fix(workspace):=20OFFSEC-003=20=E2=80=94=20sani?= =?UTF-8?q?tize=20summary/response=5Fpreview=20in=20JSON=20endpoint=20of?= =?UTF-8?q?=20read=5Fdelegation=5Fresults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the second unsanitized exit point flagged in issue #413: - task_id filter path: sanitize summary + response_preview before returning raw delegation object - list path (all recent): sanitize both fields in every delegation entry before embedding in JSON Both are peer-supplied delegation ledger data returned via the JSON polling endpoint. Sync path (lines 173, 182) was already fixed in #416. Co-Authored-By: Claude Opus 4.7 --- workspace/a2a_tools_delegation.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/workspace/a2a_tools_delegation.py b/workspace/a2a_tools_delegation.py index 720d314a..0f728ad7 100644 --- a/workspace/a2a_tools_delegation.py +++ b/workspace/a2a_tools_delegation.py @@ -414,7 +414,11 @@ async def tool_check_task_status( # Filter by delegation_id matching = [d for d in delegations if d.get("delegation_id") == task_id] if matching: - return json.dumps(matching[0]) + # OFFSEC-003: sanitize peer-supplied fields + d = matching[0] + d["summary"] = sanitize_a2a_result(d.get("summary", "")) + d["response_preview"] = sanitize_a2a_result(d.get("response_preview", "")) + return json.dumps(d) return json.dumps({"status": "not_found", "delegation_id": task_id}) # Return all recent delegations summary = [] @@ -423,8 +427,9 @@ async def tool_check_task_status( "delegation_id": d.get("delegation_id", ""), "target_id": d.get("target_id", ""), "status": d.get("status", ""), - "summary": d.get("summary", ""), - "response_preview": d.get("response_preview", ""), + # OFFSEC-003: sanitize peer-supplied fields before embedding in JSON + "summary": sanitize_a2a_result(d.get("summary", "")), + "response_preview": sanitize_a2a_result(d.get("response_preview", "")), }) return json.dumps({"delegations": summary, "count": len(delegations)}) except Exception as e: