107 @param context security context object |
107 @param context security context object |
108 @type SecurityContext |
108 @type SecurityContext |
109 @param config dictionary with configuration data |
109 @param config dictionary with configuration data |
110 @type dict |
110 @type dict |
111 """ |
111 """ |
112 if config and "shell_injection_subprocess" in config: |
112 functionNames = ( |
113 functionNames = config["shell_injection_subprocess"] |
113 config["shell_injection_subprocess"] |
114 else: |
114 if config and "shell_injection_subprocess" in config else |
115 functionNames = SecurityDefaults["shell_injection_subprocess"] |
115 SecurityDefaults["shell_injection_subprocess"] |
|
116 ) |
116 |
117 |
117 if context.callFunctionNameQual in functionNames: |
118 if context.callFunctionNameQual in functionNames: |
118 shell, shellValue = hasShell(context) |
119 shell, shellValue = hasShell(context) |
119 if shell and shellValue: |
120 if shell and shellValue and len(context.callArgs) > 0: |
120 if len(context.callArgs) > 0: |
121 sev = _evaluateShellCall(context) |
121 sev = _evaluateShellCall(context) |
122 if sev == "L": |
122 if sev == "L": |
123 reportError( |
123 reportError( |
124 context.getLinenoForCallArg('shell') - 1, |
124 context.getLinenoForCallArg('shell') - 1, |
125 context.getOffsetForCallArg('shell'), |
125 context.getOffsetForCallArg('shell'), |
126 "S602.L", |
126 "S602.L", |
127 sev, |
127 sev, |
128 "H", |
128 "H", |
129 ) |
129 ) |
130 else: |
130 else: |
131 reportError( |
131 reportError( |
132 context.getLinenoForCallArg('shell') - 1, |
132 context.getLinenoForCallArg('shell') - 1, |
133 context.getOffsetForCallArg('shell'), |
133 context.getOffsetForCallArg('shell'), |
134 "S602.H", |
134 "S602.H", |
135 sev, |
135 sev, |
136 "H", |
136 "H", |
137 ) |
137 ) |
|
138 |
138 |
139 |
139 |
140 def checkSubprocessPopenWithoutShell(reportError, context, config): |
140 def checkSubprocessPopenWithoutShell(reportError, context, config): |
141 """ |
141 """ |
142 Function to check for use of popen without shell equals true. |
142 Function to check for use of popen without shell equals true. |
146 @param context security context object |
146 @param context security context object |
147 @type SecurityContext |
147 @type SecurityContext |
148 @param config dictionary with configuration data |
148 @param config dictionary with configuration data |
149 @type dict |
149 @type dict |
150 """ |
150 """ |
151 if config and "shell_injection_subprocess" in config: |
151 functionNames = ( |
152 functionNames = config["shell_injection_subprocess"] |
152 config["shell_injection_subprocess"] |
153 else: |
153 if config and "shell_injection_subprocess" in config else |
154 functionNames = SecurityDefaults["shell_injection_subprocess"] |
154 SecurityDefaults["shell_injection_subprocess"] |
155 |
155 ) |
156 if context.callFunctionNameQual in functionNames: |
156 |
157 if not hasShell(context)[0]: |
157 if ( |
158 reportError( |
158 context.callFunctionNameQual in functionNames and |
159 context.node.lineno - 1, |
159 not hasShell(context)[0] |
160 context.node.col_offset, |
160 ): |
161 "S603", |
161 reportError( |
162 "L", |
162 context.node.lineno - 1, |
163 "H", |
163 context.node.col_offset, |
164 ) |
164 "S603", |
|
165 "L", |
|
166 "H", |
|
167 ) |
165 |
168 |
166 |
169 |
167 def checkOtherFunctionWithShell(reportError, context, config): |
170 def checkOtherFunctionWithShell(reportError, context, config): |
168 """ |
171 """ |
169 Function to check for any function with shell equals true. |
172 Function to check for any function with shell equals true. |
173 @param context security context object |
176 @param context security context object |
174 @type SecurityContext |
177 @type SecurityContext |
175 @param config dictionary with configuration data |
178 @param config dictionary with configuration data |
176 @type dict |
179 @type dict |
177 """ |
180 """ |
178 if config and "shell_injection_subprocess" in config: |
181 functionNames = ( |
179 functionNames = config["shell_injection_subprocess"] |
182 config["shell_injection_subprocess"] |
180 else: |
183 if config and "shell_injection_subprocess" in config else |
181 functionNames = SecurityDefaults["shell_injection_subprocess"] |
184 SecurityDefaults["shell_injection_subprocess"] |
|
185 ) |
182 |
186 |
183 if context.callFunctionNameQual not in functionNames: |
187 if context.callFunctionNameQual not in functionNames: |
184 shell, shellValue = hasShell(context) |
188 shell, shellValue = hasShell(context) |
185 if shell and shellValue: |
189 if shell and shellValue: |
186 reportError( |
190 reportError( |
201 @param context security context object |
205 @param context security context object |
202 @type SecurityContext |
206 @type SecurityContext |
203 @param config dictionary with configuration data |
207 @param config dictionary with configuration data |
204 @type dict |
208 @type dict |
205 """ |
209 """ |
206 if config and "shell_injection_shell" in config: |
210 functionNames = ( |
207 functionNames = config["shell_injection_shell"] |
211 config["shell_injection_shell"] |
208 else: |
212 if config and "shell_injection_shell" in config else |
209 functionNames = SecurityDefaults["shell_injection_shell"] |
213 SecurityDefaults["shell_injection_shell"] |
210 |
214 ) |
211 if context.callFunctionNameQual in functionNames: |
215 |
212 if len(context.callArgs) > 0: |
216 if ( |
213 sev = _evaluateShellCall(context) |
217 context.callFunctionNameQual in functionNames and |
214 if sev == "L": |
218 len(context.callArgs) > 0 |
215 reportError( |
219 ): |
216 context.node.lineno - 1, |
220 sev = _evaluateShellCall(context) |
217 context.node.col_offset, |
221 if sev == "L": |
218 "S605.L", |
222 reportError( |
219 sev, |
223 context.node.lineno - 1, |
220 "H", |
224 context.node.col_offset, |
221 ) |
225 "S605.L", |
222 else: |
226 sev, |
223 reportError( |
227 "H", |
224 context.node.lineno - 1, |
228 ) |
225 context.node.col_offset, |
229 else: |
226 "S605.H", |
230 reportError( |
227 sev, |
231 context.node.lineno - 1, |
228 "H", |
232 context.node.col_offset, |
229 ) |
233 "S605.H", |
|
234 sev, |
|
235 "H", |
|
236 ) |
230 |
237 |
231 |
238 |
232 def checkStartProcessWithNoShell(reportError, context, config): |
239 def checkStartProcessWithNoShell(reportError, context, config): |
233 """ |
240 """ |
234 Function to check for starting a process with no shell. |
241 Function to check for starting a process with no shell. |
238 @param context security context object |
245 @param context security context object |
239 @type SecurityContext |
246 @type SecurityContext |
240 @param config dictionary with configuration data |
247 @param config dictionary with configuration data |
241 @type dict |
248 @type dict |
242 """ |
249 """ |
243 if config and "shell_injection_noshell" in config: |
250 functionNames = ( |
244 functionNames = config["shell_injection_noshell"] |
251 config["shell_injection_noshell"] |
245 else: |
252 if config and "shell_injection_noshell" in config else |
246 functionNames = SecurityDefaults["shell_injection_noshell"] |
253 SecurityDefaults["shell_injection_noshell"] |
|
254 ) |
247 |
255 |
248 if context.callFunctionNameQual in functionNames: |
256 if context.callFunctionNameQual in functionNames: |
249 reportError( |
257 reportError( |
250 context.node.lineno - 1, |
258 context.node.lineno - 1, |
251 context.node.col_offset, |
259 context.node.col_offset, |
264 @param context security context object |
272 @param context security context object |
265 @type SecurityContext |
273 @type SecurityContext |
266 @param config dictionary with configuration data |
274 @param config dictionary with configuration data |
267 @type dict |
275 @type dict |
268 """ |
276 """ |
269 if config and "shell_injection_subprocess" in config: |
277 functionNames = ( |
270 functionNames = config["shell_injection_subprocess"] |
278 config["shell_injection_subprocess"] |
271 else: |
279 if config and "shell_injection_subprocess" in config else |
272 functionNames = SecurityDefaults["shell_injection_subprocess"] |
280 SecurityDefaults["shell_injection_subprocess"] |
|
281 ) |
273 |
282 |
274 if config and "shell_injection_shell" in config: |
283 if config and "shell_injection_shell" in config: |
275 functionNames += config["shell_injection_shell"] |
284 functionNames += config["shell_injection_shell"] |
276 else: |
285 else: |
277 functionNames += SecurityDefaults["shell_injection_shell"] |
286 functionNames += SecurityDefaults["shell_injection_shell"] |
279 if config and "shell_injection_noshell" in config: |
288 if config and "shell_injection_noshell" in config: |
280 functionNames += config["shell_injection_noshell"] |
289 functionNames += config["shell_injection_noshell"] |
281 else: |
290 else: |
282 functionNames += SecurityDefaults["shell_injection_noshell"] |
291 functionNames += SecurityDefaults["shell_injection_noshell"] |
283 |
292 |
284 if len(context.callArgs): |
293 if ( |
285 if context.callFunctionNameQual in functionNames: |
294 len(context.callArgs) and |
286 node = context.node.args[0] |
295 context.callFunctionNameQual in functionNames |
287 |
296 ): |
288 # some calls take an arg list, check the first part |
297 node = context.node.args[0] |
289 if isinstance(node, ast.List): |
298 |
290 node = node.elts[0] |
299 # some calls take an arg list, check the first part |
291 |
300 if isinstance(node, ast.List): |
292 # make sure the param is a string literal and not a var name |
301 node = node.elts[0] |
293 if ( |
302 |
294 AstUtilities.isString(node) and |
303 # make sure the param is a string literal and not a var name |
295 not fullPathMatchRe.match(node.s) |
304 if ( |
296 ): |
305 AstUtilities.isString(node) and |
297 reportError( |
306 not fullPathMatchRe.match(node.s) |
298 context.node.lineno - 1, |
307 ): |
299 context.node.col_offset, |
308 reportError( |
300 "S607", |
309 context.node.lineno - 1, |
301 "L", |
310 context.node.col_offset, |
302 "H", |
311 "S607", |
303 ) |
312 "L", |
|
313 "H", |
|
314 ) |