@@ -47,4 +47,260 @@ def refute_attack(command, input = command, reason = "[#{input}] was blocked")
4747 refute_attack "ls '$(echo \" Inner: $(echo \" This is nested\" )\" )'" ,
4848 '$(echo "Inner: $(echo "This is nested")")'
4949 end
50+
51+ test "it detects `command`" do
52+ assert_attack "echo `echo`" , "`echo`"
53+ end
54+
55+ test "it checks unsafely quoted" do
56+ assert_attack "ls '$(echo)`" , "$(echo)"
57+ end
58+
59+ test "single quote between single quotes" do
60+ assert_attack "ls ''single quote''" , "'single quote'"
61+ end
62+
63+ test "it ignores escaped backticks" do
64+ refute_attack "binary --domain www.example\\ `whoami\\ `.com" , "www.example`whoami`.com"
65+ end
66+
67+ test "it does not allow special chars inside double quotes" do
68+ assert_attack "ls \" whatever$\" " , "whatever$"
69+ assert_attack "ls \" whatever!\" " , "whatever!"
70+ assert_attack "ls \" whatever`\" " , "whatever`"
71+ end
72+
73+ test "it does not allow semi" do
74+ assert_attack "ls whatever;" , "whatever;"
75+ refute_attack "ls \" whatever;\" " , "whatever;"
76+ refute_attack "ls 'whatever;'" , "whatever;"
77+ end
78+
79+ test "rm rf executed by using semi colon" do
80+ assert_attack "ls; rm -rf" , "; rm -rf"
81+ end
82+
83+ test "rm rf is flagged as shell injection" do
84+ assert_attack "rm -rf" , "rm -rf"
85+ end
86+
87+ test "it detects shell injection with chained commands using &&" do
88+ assert_attack "ls && rm -rf /" , "&& rm -rf /"
89+ end
90+
91+ test "it detects shell injection with OR logic using ||" do
92+ assert_attack "ls || echo 'malicious code'" , "|| echo 'malicious code'"
93+ end
94+
95+ test "it detects redirection attempts" do
96+ assert_attack "ls > /dev/null" , "> /dev/null"
97+ assert_attack "cat file.txt > /etc/passwd" , "> /etc/passwd"
98+ end
99+
100+ test "it detects append redirection attempts" do
101+ assert_attack "echo 'data' >> /etc/passwd" , ">> /etc/passwd"
102+ end
103+
104+ test "it detects pipe character as potential shell injection" do
105+ assert_attack "cat file.txt | grep 'password'" , "| grep 'password'"
106+ end
107+
108+ test "it allows safe use of pipe character within quotes" do
109+ refute_attack "echo '|'" , "|"
110+ end
111+
112+ test "it detects nested command substitution" do
113+ assert_attack "echo $(cat $(ls))" , "$(cat $(ls))"
114+ end
115+
116+ test "it allows safe commands within single quotes" do
117+ refute_attack "echo 'safe command'" , "safe command"
118+ end
119+
120+ test "it detects unsafe use of variables" do
121+ assert_attack "echo $USER" , "$USER"
122+ assert_attack "echo ${USER}" , "${USER}"
123+ assert_attack 'echo "${USER}"' , "${USER}"
124+ end
125+
126+ test "it allows safe use of variables within quotes" do
127+ refute_attack "echo '$USER'" , "$USER"
128+ end
129+
130+ test "it detects subshell execution within backticks inside double quotes" do
131+ assert_attack "ls \" $(echo `whoami`)\" " , "`whoami`"
132+ end
133+
134+ test "it detects code injection with newline characters" do
135+ assert_attack "echo 'safe'\n echo 'malicious'" , "\n echo 'malicious'"
136+ end
137+
138+ test "it detects attempts to escape out of quotes" do
139+ assert_attack 'echo "safe"; echo "malicious"' , '"; echo "malicious"'
140+ end
141+
142+ test "it correctly handles whitespace in inputs" do
143+ refute_attack "ls" , " "
144+ assert_attack "ls ; rm -rf /" , "; rm -rf /"
145+ end
146+
147+ test "it detects file manipulation commands" do
148+ assert_attack "touch /tmp/malicious" , "touch /tmp/malicious"
149+ assert_attack "mv /tmp/safe /tmp/malicious" , "mv /tmp/safe /tmp/malicious"
150+ end
151+
152+ test "allows commands with constants that resemble user input but are safely encapsulated" do
153+ refute_attack "echo 'userInput'" , "userInput"
154+ end
155+
156+ test "recognizes safe paths that include patterns similar to user input" do
157+ refute_attack "ls /constant/path/without/user/input/" , "/constant/path/without/user/input/"
158+ end
159+
160+ test "acknowledges safe use of special characters when properly encapsulated" do
161+ refute_attack 'echo ";"' , ";"
162+ refute_attack 'echo "&&"' , "&&"
163+ refute_attack 'echo "||"' , "||"
164+ end
165+
166+ test "treats encapsulated redirection and pipe symbols as safe" do
167+ refute_attack "echo 'data > file.txt'" , "data > file.txt"
168+ refute_attack "echo 'find | grep'" , "find | grep"
169+ end
170+
171+ test "recognizes safe inclusion of special patterns within quotes as non-injections" do
172+ refute_attack "echo '$(command)'" , "$(command)"
173+ end
174+
175+ test "considers constants with semicolons as safe when clearly non-executable" do
176+ refute_attack "echo 'text; more text'" , "text; more text"
177+ end
178+
179+ test "acknowledges commands that look dangerous but are actually safe due to quoting" do
180+ refute_attack "echo '; rm -rf /'" , "; rm -rf /"
181+ refute_attack "echo '&& echo malicious'" , "&& echo malicious"
182+ end
183+
184+ test "recognizes commands with newline characters as safe when encapsulated" do
185+ refute_attack "echo 'line1\n line2'" , "line1\n line2"
186+ end
187+
188+ test "accepts special characters in constants as safe when they do not lead to command execution" do
189+ refute_attack "echo '*'" , "*"
190+ refute_attack "echo '?'" , "?"
191+ refute_attack "echo '\\ ' " , "\\ "
192+ end
193+
194+ test "does not flag command with matching whitespace as injection" do
195+ refute_attack "ls -l" , " " # A single space is just an argument separator, not user input
196+ end
197+
198+ test "ignores commands where multiple spaces match user input" do
199+ refute_attack "ls -l" , " " # Multiple spaces between arguments should not be considered injection
200+ end
201+
202+ test "does not consider leading whitespace in commands as user input" do
203+ refute_attack " ls -l" , " " # Leading spaces before the command are not user-controlled
204+ end
205+
206+ test "treats trailing whitespace in commands as non-injection" do
207+ refute_attack "ls -l " , " " # Trailing space after the command is benign
208+ end
209+
210+ test "recognizes spaces between quotes as non-injective" do
211+ refute_attack "echo ' ' " , " " # Space within quotes is part of the argument, not a separator
212+ end
213+
214+ test "handles spaces within quoted arguments correctly" do
215+ refute_attack "command 'arg with spaces'" , " " # Spaces within a quoted argument should not be flagged
216+ end
217+
218+ test "correctly interprets spaces in mixed argument types" do
219+ refute_attack "command arg1 'arg with spaces' arg2" , " " # Mixed argument types with internal spaces are safe
220+ end
221+
222+ test "ignores spaces in commands with concatenated arguments" do
223+ refute_attack "command 'arg1'arg2'arg3'" , " " # Lack of spaces in concatenated arguments is intentional and safe
224+ end
225+
226+ test "does not flag spaces in commands with no arguments" do
227+ refute_attack "command" , " " # No arguments mean spaces are irrelevant
228+ end
229+
230+ test "considers spaces in environment variable assignments as safe" do
231+ refute_attack "ENV_VAR='value' command" , " " # Spaces around environment variable assignments are not injections
232+ end
233+
234+ test "new lines in commands are considered injections" do
235+ assert_attack "ls \n rm" , "\n rm"
236+ assert_attack "ls \n rm -rf" , "\n rm -rf"
237+ end
238+
239+ test "new lines alone are not considered injections" do
240+ refute_attack "ls\n \n " , "\n \n "
241+ end
242+
243+ test "certain commands are always flagged as dangerous" do
244+ assert_attack "/bin/rm -rf" , "/bin/rm -rf"
245+ assert_attack "rm -rf" , "rm -rf"
246+ assert_attack "rm -rf /" , "rm -rf /"
247+ assert_attack "sleep 10" , "sleep 10"
248+ assert_attack "sleep 10 &" , "sleep 10 &"
249+ assert_attack "shutdown -h now" , "shutdown -h now"
250+ assert_attack "halt" , "halt"
251+ assert_attack "poweroff" , "poweroff"
252+ assert_attack "reboot" , "reboot"
253+ assert_attack "reboot -f" , "reboot -f"
254+ assert_attack "ifconfig" , "ifconfig"
255+ assert_attack "ifconfig -a" , "ifconfig -a"
256+ assert_attack "kill" , "kill"
257+ assert_attack "killall" , "killall"
258+ assert_attack "killall -9" , "killall -9"
259+ assert_attack "chmod" , "chmod"
260+ assert_attack "chmod 777" , "chmod 777"
261+ assert_attack "chown" , "chown"
262+ assert_attack "chown root" , "chown root"
263+ end
264+
265+ test "rm being part of other commands" do
266+ assert_attack "find /path/to/search -type f -name \" pattern\" | xargs rm" , "rm"
267+ assert_attack "find /path/to/search -type f -name \" pattern\" -exec rm {} \\ ;" , "rm"
268+ assert_attack "ls .|rm" , "rm"
269+ end
270+
271+ test "it ignores dangerous commands if they are part of a string" do
272+ refute_attack "binary sleepwithme" , "sleepwithme"
273+ refute_attack "binary rm-rf" , "rm-rf"
274+ refute_attack "term" , "term"
275+ refute_attack "rm /files/rm.txt" , "rm.txt"
276+ end
277+
278+ test "it does not flag domain name as argument unless it contains backticks" do
279+ refute_attack "binary --domain www.example.com" , "www.example.com"
280+ refute_attack "binary --domain https://www.example.com" , "https://www.example.com"
281+ assert_attack "binary --domain www.example`whoami`.com" , "www.example`whoami`.com"
282+ assert_attack "binary --domain https://www.example`whoami`.com" , "https://www.example`whoami`.com"
283+ end
284+
285+ test "it flags colon if used as a command" do
286+ assert_attack ":|echo" , ":|"
287+ assert_attack ":| echo" , ":|"
288+ assert_attack ": | echo" , ": |"
289+ end
290+
291+ test "it detects shell injection" do
292+ assert_attack "/usr/bin/kill" , "/usr/bin/kill"
293+ end
294+
295+ test "it detects shell injection with uppercase path" do
296+ assert_attack "/usr/bIn/kill" , "/usr/bIn/kill"
297+ end
298+
299+ test "it detects shell injection with uppercase command" do
300+ assert_attack "/bin/kill" , "/bin/kill"
301+ end
302+
303+ test "it detects shell injection with uppercase characters" do
304+ assert_attack "rm -rf" , "rm -rf"
305+ end
50306end
0 commit comments