11import java .lang .ProcessBuilder ;
22import java .util .List ;
33import java .util .ArrayList ;
4+ import java .util .Arrays ;
45
56class Test {
67 public static void shellCommand (String arg ) throws java .io .IOException {
@@ -28,22 +29,190 @@ public static void shellCommand(String arg) throws java.io.IOException {
2829 public static void nonShellCommand (String arg ) throws java .io .IOException {
2930 ProcessBuilder pb = new ProcessBuilder ("./customTool " + arg ); // $ Alert[java/concatenated-command-line] Alert[java/command-line-injection]
3031 pb .start ();
32+ }
3133
32- pb = new ProcessBuilder (new String []{"./customTool" , arg });
33- pb .start ();
34+ public static void nonShellCommandLiteralArguments (String arg ) throws java .io .IOException {
35+ new ProcessBuilder (new String []{"./customTool" , arg }).start (); // GOOD
36+ }
3437
38+ public static void nonShellCommandListArguments (String arg ) throws java .io .IOException {
3539 List <String > cmd = new ArrayList <String >();
3640 cmd .add ("./customTool" );
3741 cmd .add (arg );
42+ new ProcessBuilder (cmd ).start (); // GOOD
43+ }
3844
39- pb = new ProcessBuilder (cmd );
40- pb .start ();
41-
45+ public static void nonShellCommandArrayArguments (String arg ) throws java .io .IOException {
4246 String [] cmd1 = new String []{"./customTool" , "<arg>" };
4347 cmd1 [1 ] = arg ;
48+ new ProcessBuilder (cmd1 ).start (); // GOOD
49+ }
4450
45- pb = new ProcessBuilder (cmd1 );
46- pb .start ();
51+ public static void nonShellCommandWithIntermediateRead (String arg ) throws java .io .IOException {
52+ List <String > readList = new ArrayList <String >();
53+ readList .add ("./customTool" );
54+ readList .size ();
55+ readList .add (arg );
56+ new ProcessBuilder (readList ).start (); // GOOD
57+ }
58+
59+ public static void nonShellCommandWithAddAll (String arg ) throws java .io .IOException {
60+ List <String > addAllList = new ArrayList <String >();
61+ addAllList .add ("./customTool" );
62+ addAllList .addAll (Arrays .asList ("-v" ));
63+ addAllList .add (arg );
64+ new ProcessBuilder (addAllList ).start (); // GOOD
65+ }
66+
67+ public static void delegatingLauncherLiterals (String arg ) throws java .io .IOException {
68+ new ProcessBuilder (new String []{"/usr/bin/env" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
69+ new ProcessBuilder (new String []{"/usr/bin/sudo" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
70+ new ProcessBuilder (new String []{"/usr/bin/xargs" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
71+ new ProcessBuilder (new String []{"/usr/sbin/chroot" , "/tmp/root" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
72+ new ProcessBuilder (new String []{"/usr/bin/nice" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
73+ new ProcessBuilder (new String []{"/usr/bin/nohup" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
74+ new ProcessBuilder (new String []{"/usr/bin/setsid" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
75+ new ProcessBuilder (new String []{"/usr/bin/stdbuf" , "-oL" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
76+ new ProcessBuilder (new String []{"/usr/bin/timeout" , "10" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
77+ new ProcessBuilder (new String []{"/usr/bin/env" , "/bin/sh" , "-c" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
78+ }
79+
80+ public static void fixedDelegatingLauncherLiteral (String arg ) throws java .io .IOException {
81+ new ProcessBuilder (new String []{"/usr/bin/env" , "/bin/cp" , arg , "/tmp/destination" }).start (); // GOOD
82+ }
83+
84+ public static void fixedDelegatingLauncherLiteralWithPrefix (String arg )
85+ throws java .io .IOException {
86+ new ProcessBuilder (new String []{"/usr/bin/timeout" , "10" , "/bin/cp" , arg , "/tmp/destination" }).start (); // GOOD
87+ }
88+
89+ public static void delegatingLauncherListAlerts (String arg , boolean condition )
90+ throws java .io .IOException {
91+ List <String > delegatedList = new ArrayList <String >();
92+ delegatedList .add ("/usr/bin/env" );
93+ delegatedList .add (arg );
94+ new ProcessBuilder (delegatedList ).start (); // $ MISSING: Alert[java/command-line-injection]
95+
96+ List <String > branchingPosition = new ArrayList <String >();
97+ branchingPosition .add ("/usr/bin/timeout" );
98+ if (condition ) {
99+ branchingPosition .add ("10" );
100+ }
101+ branchingPosition .add (arg );
102+ new ProcessBuilder (branchingPosition ).start (); // $ MISSING: Alert[java/command-line-injection]
103+
104+ List <String > branchingLauncher = new ArrayList <String >();
105+ if (condition ) {
106+ branchingLauncher .add ("/usr/bin/env" );
107+ } else {
108+ branchingLauncher .add ("/usr/bin/timeout" );
109+ }
110+ branchingLauncher .add ("10" );
111+ branchingLauncher .add (arg );
112+ new ProcessBuilder (branchingLauncher ).start (); // $ MISSING: Alert[java/command-line-injection]
113+ }
114+
115+ public static void fixedDelegatingLauncherLaterListArgument (String arg )
116+ throws java .io .IOException {
117+ List <String > laterArgumentList = new ArrayList <String >();
118+ laterArgumentList .add ("/usr/bin/timeout" );
119+ laterArgumentList .add ("10" );
120+ laterArgumentList .add ("/bin/cp" );
121+ laterArgumentList .add (arg );
122+ laterArgumentList .add ("/tmp/destination" );
123+ new ProcessBuilder (laterArgumentList ).start (); // GOOD
124+ }
125+
126+ public static void fixedDelegatingLauncherList (String arg ) throws java .io .IOException {
127+ List <String > fixedList = new ArrayList <String >();
128+ fixedList .add ("/usr/bin/env" );
129+ fixedList .add ("/bin/cp" );
130+ fixedList .add (arg );
131+ fixedList .add ("/tmp/destination" );
132+ new ProcessBuilder (fixedList ).start (); // GOOD
133+ }
134+
135+ public static void fixedDelegatingLauncherLoopList (String arg ) throws java .io .IOException {
136+ List <String > loopList = new ArrayList <String >();
137+ loopList .add ("/usr/bin/env" );
138+ loopList .add ("/bin/cp" );
139+ for (String value : Arrays .asList (arg )) {
140+ loopList .add (value );
141+ }
142+ new ProcessBuilder (loopList ).start (); // GOOD
143+ }
144+
145+ public static void delegatingLauncherArrayAlerts (String arg , boolean condition )
146+ throws java .io .IOException {
147+ String [] delegatedArray = new String [2 ];
148+ delegatedArray [0 ] = "/usr/bin/env" ;
149+ delegatedArray [1 ] = arg ;
150+ new ProcessBuilder (delegatedArray ).start (); // $ MISSING: Alert[java/command-line-injection]
151+
152+ String launcher ;
153+ if (condition ) {
154+ launcher = "/usr/bin/env" ;
155+ } else {
156+ launcher = "/usr/bin/timeout" ;
157+ }
158+ new ProcessBuilder (new String []{launcher , "10" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
159+ }
160+
161+ public static void fixedDelegatingLauncherArray (String arg ) throws java .io .IOException {
162+ String [] fixedArray = new String []{"/usr/bin/env" , "/bin/cp" , "<arg>" , "/tmp/destination" };
163+ fixedArray [2 ] = arg ;
164+ new ProcessBuilder (fixedArray ).start (); // GOOD
165+ }
166+
167+ public static void changedDelegatedCommand (String arg ) throws java .io .IOException {
168+ String [] command = new String []{"/usr/bin/env" , "/bin/cp" , "-c" , arg };
169+ command [1 ] = "/bin/sh" ;
170+ new ProcessBuilder (command ).start (); // $ MISSING: Alert[java/command-line-injection]
171+
172+ String [] copiedInline =
173+ Arrays .copyOf (new String []{"/usr/bin/env" , "/bin/cp" , "-c" , arg }, 4 );
174+ copiedInline [1 ] = "/bin/sh" ;
175+ new ProcessBuilder (copiedInline ).start (); // $ MISSING: Alert[java/command-line-injection]
176+
177+ String [] base = new String []{"/usr/bin/env" , "/bin/cp" , "-c" , arg };
178+ String [] copiedStored = Arrays .copyOf (base , 4 );
179+ copiedStored [1 ] = "/bin/sh" ;
180+ new ProcessBuilder (copiedStored ).start (); // $ MISSING: Alert[java/command-line-injection]
181+ }
182+
183+ public static String [] returnedNonShellCommand (String arg ) {
184+ return new String []{"./customTool" , arg };
185+ }
186+
187+ public static void nestedNonShellCommand (String arg ) throws java .io .IOException {
188+ new ProcessBuilder (
189+ arg .isEmpty ()
190+ ? new String []{"./customTool" , arg }
191+ : new String []{"./otherCustomTool" , arg })
192+ .start (); // GOOD
193+ }
194+
195+ public static void useReturnedNonShellCommand (String arg ) throws java .io .IOException {
196+ new ProcessBuilder (returnedNonShellCommand (arg )).start (); // GOOD
197+ }
198+
199+ public static void unknownDelegatedCommand (String arg , String command ) throws java .io .IOException {
200+ new ProcessBuilder (new String []{"/usr/bin/env" , command , "-c" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
201+ }
202+
203+ public static void unsupportedEnvAssignment (String arg ) throws java .io .IOException {
204+ new ProcessBuilder (new String []{"/usr/bin/env" , "LANG=C" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
205+ }
206+
207+ public static void unsupportedSudoOption (String arg ) throws java .io .IOException {
208+ new ProcessBuilder (new String []{"/usr/bin/sudo" , "-u" , "nobody" , arg }).start (); // $ MISSING: Alert[java/command-line-injection]
209+ }
210+
211+ public static void changedDelegatedCommandThroughAlias (String arg ) throws java .io .IOException {
212+ String [] command = new String []{"/usr/bin/env" , "/bin/cp" , "-c" , arg };
213+ String [] alias = command ;
214+ alias [1 ] = "/bin/sh" ;
215+ new ProcessBuilder (command ).start (); // $ MISSING: Alert[java/command-line-injection]
47216 }
48217
49218 public static void relativeCommand () throws java .io .IOException {
@@ -59,6 +228,27 @@ public static void main(String[] args) throws java.io.IOException { // $ Source[
59228
60229 shellCommand (arg );
61230 nonShellCommand (arg );
231+ nonShellCommandLiteralArguments (arg );
232+ nonShellCommandListArguments (arg );
233+ nonShellCommandArrayArguments (arg );
234+ nonShellCommandWithIntermediateRead (arg );
235+ nonShellCommandWithAddAll (arg );
236+ delegatingLauncherLiterals (arg );
237+ fixedDelegatingLauncherLiteral (arg );
238+ fixedDelegatingLauncherLiteralWithPrefix (arg );
239+ delegatingLauncherListAlerts (arg , args .length > 2 );
240+ fixedDelegatingLauncherLaterListArgument (arg );
241+ fixedDelegatingLauncherList (arg );
242+ fixedDelegatingLauncherLoopList (arg );
243+ delegatingLauncherArrayAlerts (arg , args .length > 2 );
244+ fixedDelegatingLauncherArray (arg );
245+ changedDelegatedCommand (arg );
246+ nestedNonShellCommand (arg );
247+ useReturnedNonShellCommand (arg );
248+ unknownDelegatedCommand (arg , "/bin/sh" );
249+ unsupportedEnvAssignment (arg );
250+ unsupportedSudoOption (arg );
251+ changedDelegatedCommandThroughAlias (arg );
62252 relativeCommand ();
63253 }
64254}
0 commit comments