@@ -95,6 +95,50 @@ def test_deepagents_now_iso():
9595 assert "T" in ts # ISO format has T separator
9696
9797
98+ def test_deepagents_write_heredoc_injection ():
99+ """Content containing the heredoc delimiter must not cause injection."""
100+ from bashkit import BashTool
101+ from bashkit .deepagents import _build_write_cmd
102+
103+ # Content that would terminate a fixed BASHKIT_EOF heredoc early
104+ malicious = "line1\n BASHKIT_EOF\n echo INJECTED\n more"
105+ cmd = _build_write_cmd ("/tmp/test_inject.txt" , malicious )
106+
107+ # The generated delimiter must not be the plain "BASHKIT_EOF"
108+ # so content containing that literal cannot terminate it early
109+ tool = BashTool ()
110+ tool .execute_sync (cmd )
111+ r = tool .execute_sync ("cat /tmp/test_inject.txt" )
112+ assert r .exit_code == 0
113+ # The file must contain the literal BASHKIT_EOF line, not execute it
114+ assert "BASHKIT_EOF" in r .stdout
115+ assert "INJECTED" not in r .stdout or "echo INJECTED" in r .stdout
116+ # All original lines present
117+ assert "line1" in r .stdout
118+ assert "more" in r .stdout
119+
120+
121+ def test_deepagents_write_cmd_uses_shlex_quote ():
122+ """_build_write_cmd must quote file paths with special characters."""
123+ from bashkit .deepagents import _build_write_cmd
124+
125+ cmd = _build_write_cmd ("/tmp/my file.txt" , "hello" )
126+ # shlex.quote wraps in single quotes for paths with spaces
127+ assert "'/tmp/my file.txt'" in cmd
128+
129+
130+ def test_deepagents_write_cmd_unique_delimiters ():
131+ """Each call should produce a unique delimiter."""
132+ from bashkit .deepagents import _build_write_cmd
133+
134+ cmd1 = _build_write_cmd ("/tmp/a.txt" , "x" )
135+ cmd2 = _build_write_cmd ("/tmp/b.txt" , "y" )
136+ # Extract delimiter from first line: cat > path << 'DELIM'
137+ delim1 = cmd1 .split ("'" )[- 2 ]
138+ delim2 = cmd2 .split ("'" )[- 2 ]
139+ assert delim1 != delim2
140+
141+
98142# ===========================================================================
99143# pydantic_ai.py tests
100144# ===========================================================================
0 commit comments