Update the config file, and use yaml.safe_load()
- Parse the config file with yaml.safe_load(), not yaml.load(). - Use YAML lists for the blacklist functions/imports plugins. - Add plugins to the ShellInjection profile in the config. - Don't blacklist user-defined methods named `eval`. Change-Id: I437eedc4bfd56c96116cb92fe555968cf0f8dd63
This commit is contained in:
parent
fc91927698
commit
f0655ee323
26
bandit.yaml
26
bandit.yaml
@ -37,6 +37,8 @@ profiles:
|
||||
include:
|
||||
- subprocess_popen_with_shell_equals_true
|
||||
- any_other_function_with_shell_equals_true
|
||||
- start_process_with_a_shell
|
||||
- start_process_with_no_shell
|
||||
exclude:
|
||||
|
||||
SqlInjection:
|
||||
@ -46,32 +48,32 @@ profiles:
|
||||
blacklist_functions:
|
||||
bad_name_sets:
|
||||
- pickle:
|
||||
qualname: pickle.loads, pickle.load, pickle.Unpickler,
|
||||
cPickle.loads, cPickle.load, cPickle.Unpickler
|
||||
qualnames: [pickle.loads, pickle.load, pickle.Unpickler,
|
||||
cPickle.loads, cPickle.load, cPickle.Unpickler]
|
||||
message: "Pickle library appears to be in use, possible security issue."
|
||||
- marshal:
|
||||
qualname: marshal.load, marshal.loads
|
||||
qualnames: [marshal.load, marshal.loads]
|
||||
message: "Deserialization with the marshal module is possibly dangerous."
|
||||
- md5:
|
||||
qualname: hashlib.md5
|
||||
qualnames: [hashlib.md5]
|
||||
message: "Use of insecure MD5 hash function."
|
||||
- mktemp_q:
|
||||
qualname: tempfile.mktemp
|
||||
qualnames: [tempfile.mktemp]
|
||||
message: "Use of insecure and deprecated function (mktemp)."
|
||||
- eval:
|
||||
name: eval
|
||||
qualnames: [eval]
|
||||
message: "Use of possibly insecure function - consider using safer ast.literal_eval."
|
||||
- mark_safe:
|
||||
name: mark_safe
|
||||
names: [mark_safe]
|
||||
message: "Use of mark_safe() may expose cross-site scripting vulnerabilities and should be reviewed."
|
||||
- httpsconnection:
|
||||
qualname: httplib.HTTPSConnection
|
||||
qualnames: [httplib.HTTPSConnection]
|
||||
message: "Use of HTTPSConnection does not provide security, see https://wiki.openstack.org/wiki/OSSN/OSSN-0033"
|
||||
- yaml_load:
|
||||
qualname: yaml.load
|
||||
qualnames: [yaml.load]
|
||||
message: "Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load()."
|
||||
- urllib_urlopen:
|
||||
qualname: urllib.urlopen, urllib.urlretrieve, urllib.URLopener, urllib.FancyURLopener, urllib2.urlopen, urllib2.Request
|
||||
qualnames: [urllib.urlopen, urllib.urlretrieve, urllib.URLopener, urllib.FancyURLopener, urllib2.urlopen, urllib2.Request]
|
||||
message: "Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected."
|
||||
|
||||
shell_injection:
|
||||
@ -91,11 +93,11 @@ shell_injection:
|
||||
blacklist_imports:
|
||||
bad_import_sets:
|
||||
- telnet:
|
||||
import: telnetlib
|
||||
imports: [telnetlib]
|
||||
level: ERROR
|
||||
message: "Telnet is considered insecure. Use SSH or some other encrypted protocol."
|
||||
- info_libs:
|
||||
import: pickle, cPickle, subprocess, Crypto
|
||||
imports: [pickle, cPickle, subprocess, Crypto]
|
||||
level: INFO
|
||||
message: "Consider possible security implications associated with {module} module."
|
||||
|
||||
|
@ -44,7 +44,7 @@ class BanditConfig():
|
||||
sys.exit(2)
|
||||
else:
|
||||
# yaml parser does its own exception handling
|
||||
self._config = yaml.load(f)
|
||||
self._config = yaml.safe_load(f)
|
||||
|
||||
self._init_settings()
|
||||
|
||||
|
@ -91,20 +91,10 @@ def _get_tuple_for_item(blacklist_object):
|
||||
if not isinstance(blacklist_object, dict):
|
||||
return None
|
||||
|
||||
if 'qualname' in blacklist_object:
|
||||
qualname_list = blacklist_object['qualname'].split(',')
|
||||
for q in qualname_list:
|
||||
if not qualnames:
|
||||
qualnames = []
|
||||
qualnames.append(q.replace(' ', '').strip())
|
||||
|
||||
if 'name' in blacklist_object:
|
||||
name_list = blacklist_object['name'].split(',')
|
||||
for n in name_list:
|
||||
if not names:
|
||||
names = []
|
||||
names.append(n.replace(' ', '').strip())
|
||||
|
||||
if 'qualnames' in blacklist_object:
|
||||
qualnames = blacklist_object['qualnames']
|
||||
if 'names' in blacklist_object:
|
||||
names = blacklist_object['names']
|
||||
if 'message' in blacklist_object:
|
||||
message = blacklist_object['message']
|
||||
|
||||
@ -116,12 +106,8 @@ def _get_tuple_for_item(blacklist_object):
|
||||
elif blacklist_object['level'] == 'INFO':
|
||||
level = 'INFO'
|
||||
|
||||
if 'param' in blacklist_object:
|
||||
param_list = blacklist_object['param'].split(',')
|
||||
for p in param_list:
|
||||
if not params:
|
||||
params = []
|
||||
params.append(p.replace(' ', '').strip())
|
||||
if 'params' in blacklist_object:
|
||||
params = blacklist_object['params']
|
||||
|
||||
return_tuple = (qualnames, names, message, level, params)
|
||||
return return_tuple
|
||||
|
@ -71,18 +71,13 @@ def _get_tuple_for_item(blacklist_object):
|
||||
level = 'WARN'
|
||||
|
||||
# if the item we got passed isn't a dictionary, do nothing with the object;
|
||||
# if the item we got passed doesn't have an import field, or the import
|
||||
# isn't a string, we can't do anything with this. Return None
|
||||
if(not isinstance(blacklist_object, dict)
|
||||
or 'import' not in blacklist_object
|
||||
or not type(blacklist_object['import']) == str):
|
||||
# if the item we got passed doesn't have an imports field, we can't do
|
||||
# anything with this. Return None
|
||||
if (not isinstance(blacklist_object, dict)
|
||||
or 'imports' not in blacklist_object):
|
||||
return None
|
||||
|
||||
import_list = blacklist_object['import'].split(',')
|
||||
for i in import_list:
|
||||
if not imports:
|
||||
imports = []
|
||||
imports.append(i.replace(' ', '').strip())
|
||||
imports = blacklist_object['imports']
|
||||
|
||||
if 'message' in blacklist_object:
|
||||
message = blacklist_object['message']
|
||||
@ -94,6 +89,7 @@ def _get_tuple_for_item(blacklist_object):
|
||||
level = 'WARN'
|
||||
elif blacklist_object['level'] == 'INFO':
|
||||
level = 'INFO'
|
||||
|
||||
return_tuple = (imports, message, level)
|
||||
return return_tuple
|
||||
|
||||
|
@ -3,3 +3,13 @@ import os
|
||||
print(eval("1+1"))
|
||||
print(eval("os.getcwd()"))
|
||||
print(eval("os.chmod('%s', 0777)" % 'test.txt'))
|
||||
|
||||
|
||||
# A user-defined method named "eval" should not get flagged.
|
||||
class Test(object):
|
||||
def eval(self):
|
||||
print("hi")
|
||||
def foo(self):
|
||||
self.eval()
|
||||
|
||||
Test().eval()
|
||||
|
Loading…
x
Reference in New Issue
Block a user