114 else: |
114 else: |
115 functionNames = SecurityDefaults["shell_injection_subprocess"] |
115 functionNames = SecurityDefaults["shell_injection_subprocess"] |
116 |
116 |
117 if context.callFunctionNameQual in functionNames: |
117 if context.callFunctionNameQual in functionNames: |
118 shell, shellValue = hasShell(context) |
118 shell, shellValue = hasShell(context) |
119 if shell and shellValue: |
119 if shell and shellValue and len(context.callArgs) > 0: |
120 if len(context.callArgs) > 0: |
120 sev = _evaluateShellCall(context) |
121 sev = _evaluateShellCall(context) |
121 if sev == "L": |
122 if sev == "L": |
122 reportError( |
123 reportError( |
123 context.getLinenoForCallArg('shell') - 1, |
124 context.getLinenoForCallArg('shell') - 1, |
124 context.getOffsetForCallArg('shell'), |
125 context.getOffsetForCallArg('shell'), |
125 "S602.L", |
126 "S602.L", |
126 sev, |
127 sev, |
127 "H", |
128 "H", |
128 ) |
129 ) |
129 else: |
130 else: |
130 reportError( |
131 reportError( |
131 context.getLinenoForCallArg('shell') - 1, |
132 context.getLinenoForCallArg('shell') - 1, |
132 context.getOffsetForCallArg('shell'), |
133 context.getOffsetForCallArg('shell'), |
133 "S602.H", |
134 "S602.H", |
134 sev, |
135 sev, |
135 "H", |
136 "H", |
136 ) |
137 ) |
|
138 |
137 |
139 |
138 |
140 def checkSubprocessPopenWithoutShell(reportError, context, config): |
139 def checkSubprocessPopenWithoutShell(reportError, context, config): |
141 """ |
140 """ |
142 Function to check for use of popen without shell equals true. |
141 Function to check for use of popen without shell equals true. |
151 if config and "shell_injection_subprocess" in config: |
150 if config and "shell_injection_subprocess" in config: |
152 functionNames = config["shell_injection_subprocess"] |
151 functionNames = config["shell_injection_subprocess"] |
153 else: |
152 else: |
154 functionNames = SecurityDefaults["shell_injection_subprocess"] |
153 functionNames = SecurityDefaults["shell_injection_subprocess"] |
155 |
154 |
156 if context.callFunctionNameQual in functionNames: |
155 if ( |
157 if not hasShell(context)[0]: |
156 context.callFunctionNameQual in functionNames and |
158 reportError( |
157 not hasShell(context)[0] |
159 context.node.lineno - 1, |
158 ): |
160 context.node.col_offset, |
159 reportError( |
161 "S603", |
160 context.node.lineno - 1, |
162 "L", |
161 context.node.col_offset, |
163 "H", |
162 "S603", |
164 ) |
163 "L", |
|
164 "H", |
|
165 ) |
165 |
166 |
166 |
167 |
167 def checkOtherFunctionWithShell(reportError, context, config): |
168 def checkOtherFunctionWithShell(reportError, context, config): |
168 """ |
169 """ |
169 Function to check for any function with shell equals true. |
170 Function to check for any function with shell equals true. |
206 if config and "shell_injection_shell" in config: |
207 if config and "shell_injection_shell" in config: |
207 functionNames = config["shell_injection_shell"] |
208 functionNames = config["shell_injection_shell"] |
208 else: |
209 else: |
209 functionNames = SecurityDefaults["shell_injection_shell"] |
210 functionNames = SecurityDefaults["shell_injection_shell"] |
210 |
211 |
211 if context.callFunctionNameQual in functionNames: |
212 if ( |
212 if len(context.callArgs) > 0: |
213 context.callFunctionNameQual in functionNames and |
213 sev = _evaluateShellCall(context) |
214 len(context.callArgs) > 0 |
214 if sev == "L": |
215 ): |
215 reportError( |
216 sev = _evaluateShellCall(context) |
216 context.node.lineno - 1, |
217 if sev == "L": |
217 context.node.col_offset, |
218 reportError( |
218 "S605.L", |
219 context.node.lineno - 1, |
219 sev, |
220 context.node.col_offset, |
220 "H", |
221 "S605.L", |
221 ) |
222 sev, |
222 else: |
223 "H", |
223 reportError( |
224 ) |
224 context.node.lineno - 1, |
225 else: |
225 context.node.col_offset, |
226 reportError( |
226 "S605.H", |
227 context.node.lineno - 1, |
227 sev, |
228 context.node.col_offset, |
228 "H", |
229 "S605.H", |
229 ) |
230 sev, |
|
231 "H", |
|
232 ) |
230 |
233 |
231 |
234 |
232 def checkStartProcessWithNoShell(reportError, context, config): |
235 def checkStartProcessWithNoShell(reportError, context, config): |
233 """ |
236 """ |
234 Function to check for starting a process with no shell. |
237 Function to check for starting a process with no shell. |
279 if config and "shell_injection_noshell" in config: |
282 if config and "shell_injection_noshell" in config: |
280 functionNames += config["shell_injection_noshell"] |
283 functionNames += config["shell_injection_noshell"] |
281 else: |
284 else: |
282 functionNames += SecurityDefaults["shell_injection_noshell"] |
285 functionNames += SecurityDefaults["shell_injection_noshell"] |
283 |
286 |
284 if len(context.callArgs): |
287 if ( |
285 if context.callFunctionNameQual in functionNames: |
288 len(context.callArgs) and |
286 node = context.node.args[0] |
289 context.callFunctionNameQual in functionNames |
287 |
290 ): |
288 # some calls take an arg list, check the first part |
291 node = context.node.args[0] |
289 if isinstance(node, ast.List): |
292 |
290 node = node.elts[0] |
293 # some calls take an arg list, check the first part |
291 |
294 if isinstance(node, ast.List): |
292 # make sure the param is a string literal and not a var name |
295 node = node.elts[0] |
293 if ( |
296 |
294 AstUtilities.isString(node) and |
297 # make sure the param is a string literal and not a var name |
295 not fullPathMatchRe.match(node.s) |
298 if ( |
296 ): |
299 AstUtilities.isString(node) and |
297 reportError( |
300 not fullPathMatchRe.match(node.s) |
298 context.node.lineno - 1, |
301 ): |
299 context.node.col_offset, |
302 reportError( |
300 "S607", |
303 context.node.lineno - 1, |
301 "L", |
304 context.node.col_offset, |
302 "H", |
305 "S607", |
303 ) |
306 "L", |
|
307 "H", |
|
308 ) |