Skip to content

Commit 4e47c0c

Browse files
0xhisST-2
authored andcommitted
fix(agent): escape XML values, CDATA content, generic corrective message
- Add html.escape() to target values in <scan_task> (URLs, paths, IPs) - Escape sender_name/sender_id in <agent_message> attributes - CDATA-wrap message content in <agent_message> to handle any text - Make corrective message generic (no StrixAgent-specific tool names)
1 parent 3a8d319 commit 4e47c0c

2 files changed

Lines changed: 19 additions & 17 deletions

File tree

strix/agents/StrixAgent/strix_agent.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Any
22

3+
import html
4+
35
from strix.agents.base_agent import BaseAgent
46
from strix.llm.config import LLMConfig
57

@@ -103,24 +105,26 @@ async def execute_scan(self, scan_config: dict[str, Any]) -> dict[str, Any]: #
103105
for repo in repositories:
104106
if repo["workspace_path"]:
105107
target_lines.append(
106-
f' <target type="repository">{repo["url"]} (code at: {repo["workspace_path"]})</target>'
108+
f' <target type="repository">{html.escape(repo["url"])} (code at: {html.escape(repo["workspace_path"])})</target>'
107109
)
108110
else:
109-
target_lines.append(f' <target type="repository">{repo["url"]}</target>')
111+
target_lines.append(
112+
f' <target type="repository">{html.escape(repo["url"])}</target>'
113+
)
110114

111115
if local_code:
112116
for code in local_code:
113117
target_lines.append(
114-
f' <target type="local_code">{code["path"]} (code at: {code["workspace_path"]})</target>'
118+
f' <target type="local_code">{html.escape(code["path"])} (code at: {html.escape(code["workspace_path"])})</target>'
115119
)
116120

117121
if urls:
118122
for url in urls:
119-
target_lines.append(f' <target type="url">{url}</target>')
123+
target_lines.append(f' <target type="url">{html.escape(url)}</target>')
120124

121125
if ip_addresses:
122126
for ip in ip_addresses:
123-
target_lines.append(f' <target type="ip">{ip}</target>')
127+
target_lines.append(f' <target type="ip">{html.escape(ip)}</target>')
124128

125129
targets_block = "\n".join(target_lines)
126130

@@ -141,7 +145,7 @@ async def execute_scan(self, scan_config: dict[str, Any]) -> dict[str, Any]: #
141145
"and use other files only for context.</note>"
142146
)
143147
for repo_scope in diff_scope.get("repos", []):
144-
repo_label = (
148+
repo_label = html.escape(
145149
repo_scope.get("workspace_subdir")
146150
or repo_scope.get("source_path")
147151
or "repository"
@@ -167,6 +171,6 @@ async def execute_scan(self, scan_config: dict[str, Any]) -> dict[str, Any]: #
167171
)
168172

169173
if user_instructions:
170-
task_description += f"\n\nSpecial instructions: {user_instructions}"
174+
task_description += f"\n\nSpecial instructions: {html.escape(user_instructions)}"
171175

172176
return await self.agent_loop(task=task_description)

strix/agents/base_agent.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import contextlib
3+
import html
34
import logging
45
from typing import TYPE_CHECKING, Any, Optional
56

@@ -414,11 +415,7 @@ async def _process_iteration(self, tracer: Optional["Tracer"]) -> bool | None:
414415
corrective_message = (
415416
"You responded with plain text instead of a tool call. "
416417
"While the agent loop is running, EVERY response MUST be a tool call. "
417-
"Do NOT send plain text messages. Act via tools:\n"
418-
"- Use the think tool to reason through problems\n"
419-
"- Use create_agent to spawn subagents for testing\n"
420-
"- Use terminal_execute to run commands\n"
421-
"- Use wait_for_message ONLY when waiting for subagent results\n"
418+
"Do NOT send plain text messages. Act via your available tools. "
422419
"Review your task and take action now."
423420
)
424421
self.state.add_message("user", corrective_message)
@@ -500,12 +497,13 @@ def _check_agent_messages(self, state: AgentState) -> None: # noqa: PLR0912
500497
if sender_id and sender_id in _agent_graph.get("nodes", {}):
501498
sender_name = _agent_graph["nodes"][sender_id]["name"]
502499

500+
content = message.get("content", "")
503501
message_content = f"""<agent_message
504-
from="{sender_name}"
505-
id="{sender_id}"
506-
type="{message.get("message_type", "information")}"
507-
priority="{message.get("priority", "normal")}">
508-
{message.get("content", "")}
502+
from="{html.escape(sender_name)}"
503+
id="{html.escape(str(sender_id))}"
504+
type="{html.escape(message.get("message_type", "information"))}"
505+
priority="{html.escape(message.get("priority", "normal"))}">
506+
<![CDATA[{content}]]>
509507
</agent_message>"""
510508
state.add_message("user", message_content.strip())
511509

0 commit comments

Comments
 (0)