Modify call_bad_names test to use regex and add to blacklist

This modifies the test performed in call_bad_names to use re.match, adds
additional functions to the blacklist, and adds examples that trigger those
new blacklist entries.

It is an intial pass at addressing https://github.com/chair6/bandit/issues/6,
but further changes will be required to clean this up, including separating
configuration from test code.
This commit is contained in:
Jamie Finnigan 2014-07-25 11:07:35 -07:00
parent f6fba51313
commit cd7a2df127
5 changed files with 58 additions and 8 deletions

11
examples/os-exec.py Normal file
View File

@ -0,0 +1,11 @@
import os
os.execl(path, arg0, arg1)
os.execle(path, arg0, arg1, env)
os.execlp(file, arg0, arg1)
os.execlpe(file, arg0, arg1, env)
os.execv(path, args)
os.execve(path, args, env)
os.execvp(file, args)
os.execvpe(file, args, env)

13
examples/os-popen.py Normal file
View File

@ -0,0 +1,13 @@
import os
from os import popen
import os as o
from os import popen as pos
os.popen('/bin/uname -av')
popen('/bin/uname -av')
o.popen('/bin/uname -av')
pos('/bin/uname -av')
os.popen2('/bin/uname -av')
os.popen3('/bin/uname -av')
os.popen4('/bin/uname -av')

10
examples/os-spawn.py Normal file
View File

@ -0,0 +1,10 @@
import os
os.spawnl(mode, path)
os.spawnle(mode, path, env)
os.spawnlp(mode, file)
os.spawnlpe(mode, file, env)
os.spawnv(mode, path, args)
os.spawnve(mode, path, args, env)
os.spawnvp(mode, file, args)
os.spawnvpe(mode, file, args, env)

6
examples/os-startfile.py Normal file
View File

@ -0,0 +1,6 @@
import os
os.startfile('foo.docx')
os.startfile('bad.exe')
os.startfile('text.txt')

View File

@ -21,21 +21,31 @@ from bandit import utils
import ast
import _ast
import stat
import re
def call_bad_names(context):
# TODO - move this out into configuration
bad_name_sets = [
(['pickle.loads', 'pickle.dumps', ],
(['pickle\.((loads)|(dumps))', ],
'Pickle library appears to be in use, possible security issue.'),
(['hashlib.md5', ],
(['hashlib\.md5', ],
'Use of insecure MD5 hash function.'),
(['subprocess.Popen', ],
(['subprocess\.Popen', ],
'Use of possibly-insecure system call function '
'(subprocess.Popen).'),
(['subprocess.call', ],
(['subprocess\.call', ],
'Use of possibly-insecure system call function '
'(subprocess.call).'),
(['tempfile.mktemp', 'mktemp'],
(['os.((exec)|(spawn))((l)|(le)|(lp)|(lpe)|(v)|(ve)|(vp)|(vpe))',],
'Use of possibly-insecure system call function '
'(os.exec* or os.spawn*).'),
(['os.popen((2)|(3)|(4))*', 'popen'],
'Use of insecure / deprecated system call function '
'(os.popen).'),
(['os.startfile', 'startfile'],
'Use of insecure system function (os.startfile).'),
(['tempfile\.mktemp', 'mktemp'],
'Use of insecure and deprecated function (mktemp).'),
(['eval', ],
'Use of possibly-insecure function - consider using the safer '
@ -44,9 +54,9 @@ def call_bad_names(context):
# test for 'bad' names defined above
for bad_name_set in bad_name_sets:
for bad_name in bad_name_set[0]:
# if name.startswith(bad_name) or name.endswith(bad_name):
if context['qualname'] == bad_name:
for bad_name_regex in bad_name_set[0]:
# various tests we could do here, re.match works for now
if re.match(bad_name_regex, context['qualname']):
return(bandit.WARN, "%s %s" %
(bad_name_set[1],
utils.ast_args_to_str(context['call'].args)))