pycqa / bandit Goto Github PK
View Code? Open in Web Editor NEWBandit is a tool designed to find common security issues in Python code.
Home Page: https://bandit.readthedocs.io
License: Apache License 2.0
Bandit is a tool designed to find common security issues in Python code.
Home Page: https://bandit.readthedocs.io
License: Apache License 2.0
The screen formatter apparently has a UnicodeDecode issue when running against the Keystone /tests directory.
To reproduce:
Running Bandit on the following produces a traceback in the hardcoded password plugin:
def sort_by_release((hash, version)):
do_something()
[tester] ERROR Bandit internal error running: hardcoded_password_default on file test_traceback.py at line 1: 'Tuple' object has no attribute 'id'Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/bandit/core/tester.py", line 73, in run_tests
result = test(context)
File "/usr/local/lib/python2.7/site-packages/bandit/plugins/general_hardcoded_password.py", line 78, in hardcoded_password_default
check = key.arg if sys.version_info.major > 2 else key.id # Py3
AttributeError: 'Tuple' object has no attribute 'id'
Bandit dumps tracebacks when it fails to access files. It would be preferrable if Bandit gracefully handled the exceptions and displayed a user appropriate error. Also, it should be checking for the existence of the output file prior to running the scan.
promd-1s-dhcp317:bandit browne$ bandit -r ../openstack/ -o /Library/
86 [0.. 50.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 393, in report
with open(output_filename, 'w') as fout:
IOError: [Errno 21] Is a directory: '/Library/'
promd-1s-dhcp317:bandit browne$ bandit -r ../openstack/ -o /Library/sfd
86 [0.. 50.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 393, in report
with open(output_filename, 'w') as fout:
IOError: [Errno 13] Permission denied: '/Library/sfd'
When using the "-a vuln" option for the bandit command line, I get a KeyError.
promd-1s-dhcp317:bandit browne$ bandit -r ../glance/glance/ -a vuln
315 [0.. 50.. 100.. 150.. 200.. 250.. 300.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 382, in report
level=level) # noqa
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 324, in report_tty
issue['lineno'],
KeyError: 'lineno'
Bandit's JSON report doesn't exclude lines marked #nosec. The JSON report also doesn't respect the -l
CLI flag, which only shows higher-severity issues in the text report. The command bandit -f json -lll examples/skip.py
demonstrates both issues.
As an aside, perhaps #nosec lines shouldn't be scored at all. Right now it's up to the individual reports to filter out these lines. That's the reason tests/test_functional:FunctionalTests.test_skip
is skipped right now: #nosec lines receive a score.
Running bandit analysis against the cinder code base I am getting many of the following output:
[tester] ERROR Bandit internal error running: try_except_pass on file cinder/api/contrib/admin_actions.py at line 97: 'NoneType' object has no attribute 'getitem'Traceback (most recent call last):
File "/home/smcginnis/Documents/dev/repos/OpenStack/cinder/.tox/bandit/local/lib/python2.7/site-packages/bandit/core/tester.py", line 63, in run_tests
result = test(context, test_config)
File "/home/smcginnis/Documents/dev/repos/OpenStack/cinder/.tox/bandit/local/lib/python2.7/site-packages/bandit/plugins/try_except_pass.py", line 28, in try_except_pass
if (not config['check_typed_exception'] and
TypeError: 'NoneType' object has no attribute 'getitem'
It appears config is not being passed in by takes_config.
Other plugins using takes_config do not show this error, just try_except_pass. The other plugins also appear to be importing and declaring the decorator slightly different.
I found switching the import to match some of the other ones or keeping the import as is but adding parenthesis to the decorator makes the problem go away. Not sure how these really make a difference.
Using Python 2.7.6 on Ubuntu 14.01.
Bandit on Python3 fails to produce reports in JSON format.
The exception message that bandit displays is like:
TypeError: range(175, 176) is not JSON serializable
There seem to be (Python-2 - Python-3 portability related) bug in
File: bandit/core/utils. py
, method: linerange, statement:
return range(min(lines), max(lines) + 1))File:
bandit/core/utils. py, method:
linerange_fix, statement:
return range(start, node.sibling.lineno)`
In Python-2, range
is a method that returns a list of values. (https://docs.python.org/2/library/functions.html#range)
In Python-3, range
is a class (https://docs.python.org/3.4/library/stdtypes.html#range).
Fix: To make it compatible: the range object must be passed to list constructor.
File: bandit/core/utils. py
, method: linerange, statement:
return list(range(min(lines), max(lines) + 1)))File:
bandit/core/utils. py, method:
linerange_fix, statement:
return list(range(start, node.sibling.lineno))`
Score section in JSON output (incorrectly) shows total score instead of per file score:
"stats": [
{
"filename": "./test_file2.py",
"issue totals": {
"HIGH": 0,
"LOW": 3,
"MEDIUM": 0,
"UNDEFINED": 0
},
"score": 59
},
{
"filename": "./test_file1.py",
"issue totals": {
"HIGH": 0,
"LOW": 0,
"MEDIUM": 2,
"UNDEFINED": 0
},
"score": 59
}
The above is from the score section at the end of a JSON report. Note that the score is '59' for both, even though the two files should obviously have different scores.
When I run latest Bandit against Keystone, even if I filter for medium+ severity I still get "low" severity results:
MacBook-Pro:bandit travismcpeak$ bandit -r ~/Documents/projects/OpenStack_projects/keystone -ll
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
[general_hardcoded_password] WARNING Using relative path for word_list: ./wordlist/default-passwords
Run started:
2015-09-10 16:35:12.800785
Files skipped (0):
Test results:
Issue: Try, Except, Pass detected.
Severity: Low Confidence: High
Location: /Users/travismcpeak/Documents/projects/OpenStack_projects/keystone/.tox/bandit/lib/python2.7/_abcoll.py:325
324 self.pop()
325 except KeyError:
326 pass
When installed with no other changes, bandit will not detect any plugins. Tests end successful, even though no checks are really run.
It's not obvious unless bandit is run with --help which does provide an empty list of loaded plugins: "The following plugin suites were discovered and loaded: []"
Main issue seems to be that plugins not listed as entry points will not be detected by stevedore.
File /usr/lib/python2.7/dist-packages/idna/idnadata.py (available in most system installation) is a good testcase for recursion limit. Current bandit master breaks on the file. It should either succeed or recover gracefully with a good error message.
Running Bandit, erroneously, in the following way produces strange output:
MacBook-Pro:bandit travismcpeak$ bandit examples/multiline-str.py -3
Run started:
2015-03-20 18:23:40.705354
Files in scope (2):
-3 (score: 10)
Files excluded (0):
Files skipped (1):
-3 (No such file or directory)
Test results:
This is wrong because:
Patch https://review.openstack.org/#/c/278720 attempts to change test-requirements import of mock to be conditional for only 3.2 and lower. But the mock namespace in py34 is "unittest.mock" not just "mock" So this patch breaks on failing imports:
2016-02-10 23:35:34.138 | Failed to import test module: tests.unit.formatters.test_text
2016-02-10 23:35:34.138 | Traceback (most recent call last):
2016-02-10 23:35:34.138 | File "/home/jenkins/workspace/gate-bandit-python34/.tox/py34/lib/python3.4/site-packages/unittest2/loader.py", line 456, in _find_test_path
2016-02-10 23:35:34.138 | module = self._get_module_from_name(name)
2016-02-10 23:35:34.138 | File "/home/jenkins/workspace/gate-bandit-python34/.tox/py34/lib/python3.4/site-packages/unittest2/loader.py", line 395, in _get_module_from_name
2016-02-10 23:35:34.138 | import(name)
2016-02-10 23:35:34.139 | File "/home/jenkins/workspace/gate-bandit-python34/tests/unit/formatters/test_text.py", line 20, in
2016-02-10 23:35:34.139 | import mock
2016-02-10 23:35:34.139 | ImportError: No module named 'mock'
plugins need documentation, so that adopters know whats available and how to configure it.
As a developer I just want to point bandit at my directory and have it go. Having to use find + xargs or shell expansion shouldn't be necessary.
A system wide $ sudo pip install bandit fails to report any findings for some projects. This is a problem for some CICD work I'm doing which means I generally have to create a wrapper script like:
#!/bin/bash
source /some_virtenv/bin/activate
bandit $@
Which is less than ideal.
Steps to reproduce consistently
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", "2048"]
end
end
Actual output:
vagrant@vagrant-ubuntu-trusty-64:~/trove$ bandit -r .
[bandit] INFO using config: /usr/local/lib/python2.7/dist-packages/bandit/config/bandit.yaml
[bandit] INFO running on Python 2.7.6
476 [0.. 50.. 100.. 150.. 200.. 250.. 300.. 350.. 400.. 450.. ]
Run started:
2015-07-17 14:38:33.388857
Files skipped (0):
Test results:
No issues identified.
Expected output:
Lots of issues
When running Bandit on setup.py (from its own directory) there is an uncaught exception:
(band)MacBook-Pro:bandit travismcpeak$ bandit -n 5 setup.py
Traceback (most recent call last):
File "/Users/travismcpeak/Documents/projects/bandit/band/bin/bandit", line 10, in
sys.exit(main())
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/bandit.py", line 74, in main
b_mgr.run_scope(args.files)
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/manager.py", line 134, in run_scope
self.b_rs, self.b_ts
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/manager.py", line 170, in _execute_ast_visitor
fname, self.logger, self.b_conf, b_ma, b_rs, b_ts, self.debug
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/node_visitor.py", line 60, in init
self.namespace = b_utils.get_module_qualname_from_path(fname)
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/utils.py", line 134, in get_module_qualname_from_path
' Missing path or file name' % (path))
bandit.core.utils.InvalidModulePath: Invalid python file path: "setup.py" Missing path or file name
We should catch the exception and generate some sort of meaningful warning/log output based on it.
Bandit dumps tracebacks when it fails to access files. It would be preferrable if Bandit gracefully handled the exceptions and displayed a user appropriate error. Also, it should be checking for the existence of the output file prior to running the scan.
promd-1s-dhcp317:bandit browne$ bandit -r ../openstack/ -o /Library/
86 [0.. 50.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 393, in report
with open(output_filename, 'w') as fout:
IOError: [Errno 21] Is a directory: '/Library/'
promd-1s-dhcp317:bandit browne$ bandit -r ../openstack/ -o /Library/sfd
86 [0.. 50.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 393, in report
with open(output_filename, 'w') as fout:
IOError: [Errno 13] Permission denied: '/Library/sfd'
Bandit has an integration tox job which checks against other projects whether a bandit patch potentially breaks them. I noticed its not working as of late.
When errors occur, they are ignored. Either the exit code is not preserved or something else is happening. The job always shows success.
For example (gate-bandit-integration-keystone):
2016-02-17 19:15:01.574 | + pushd ../keystone
2016-02-17 19:15:01.574 | /home/jenkins/workspace/gate-bandit-integration-keystone/openstack/keystone /home/jenkins/workspace/gate-bandit-integration-keystone/openstack/bandit
2016-02-17 19:15:01.574 | + set +e
2016-02-17 19:15:01.574 | + tox -e bandit --notest
2016-02-17 19:15:01.663 | ERROR: unknown environment 'bandit'
2016-02-17 19:15:01.670 | + .tox/bandit/bin/pip install --force-reinstall -U /home/jenkins/workspace/gate-bandit-integration-keystone/openstack/bandit
2016-02-17 19:15:01.671 | scripts/integration-test.sh: line 48: .tox/bandit/bin/pip: No such file or directory
2016-02-17 19:15:01.671 | + tox -e bandit
2016-02-17 19:15:01.795 | ERROR: unknown environment 'bandit'
2016-02-17 19:15:01.802 | + popd
2016-02-17 19:15:01.802 | /home/jenkins/workspace/gate-bandit-integration-keystone/openstack/bandit
2016-02-17 19:15:01.802 | + [[ 0 -eq 1 ]]
2016-02-17 19:15:01.803 | ___________________________________ summary ____________________________________
2016-02-17 19:15:01.803 | integration: commands succeeded
2016-02-17 19:15:01.803 | congratulations :)
gate-bandit-integration-oslo.vmware:
2016-02-17 19:15:20.354 | �[93m>> Issue: [B309:blacklist] Use of HTTPSConnection does not provide security, see https://wiki.openstack.org/wiki/OSSN/OSSN-0033
2016-02-17 19:15:20.354 | Severity: Medium Confidence: High
2016-02-17 19:15:20.354 | Location: oslo_vmware/objects/datastore.py:313�[0m
2016-02-17 19:15:20.354 | 311 conn = httplib.HTTPConnection(self._server)
2016-02-17 19:15:20.354 | 312 elif self._scheme == 'https':
2016-02-17 19:15:20.354 | 313 conn = httplib.HTTPSConnection(self._server)
2016-02-17 19:15:20.354 | 314 else:
2016-02-17 19:15:20.354 | 315 excep_msg = _("Invalid scheme: %s.") % self._scheme
2016-02-17 19:15:20.354 |
2016-02-17 19:15:20.355 | --------------------------------------------------
2016-02-17 19:15:20.355 | �[94m>> Issue: [B112:os_path_join_traversal] Check variables used with os.path.join are trusted or sanitised.
2016-02-17 19:15:20.355 | Severity: Low Confidence: Low
2016-02-17 19:15:20.355 | Location: oslo_vmware/pbm.py:196�[0m
2016-02-17 19:15:20.355 | 194 major_minor = '%s.%s' % (major_minor, ver[1])
2016-02-17 19:15:20.355 | 195 curr_dir = os.path.abspath(os.path.dirname(file))
2016-02-17 19:15:20.355 | 196 pbm_service_wsdl = os.path.join(curr_dir, 'wsdl', major_minor,
2016-02-17 19:15:20.355 | 197 'pbmService.wsdl')
2016-02-17 19:15:20.355 | 198 if not os.path.exists(pbm_service_wsdl):
2016-02-17 19:15:20.355 | 199 LOG.warning(_LW("PBM WSDL file %s not found."), pbm_service_wsdl)
2016-02-17 19:15:20.356 |
2016-02-17 19:15:20.356 | --------------------------------------------------
2016-02-17 19:15:20.374 | ERROR: InvocationError: '/home/jenkins/workspace/gate-bandit-integration-oslo.vmware/openstack/oslo.vmware/.tox/bandit/bin/bandit -r oslo_vmware -n 5'
2016-02-17 19:15:20.374 | ___________________________________ summary ____________________________________
2016-02-17 19:15:20.374 | ERROR: bandit: commands failed
2016-02-17 19:15:20.382 | + popd
2016-02-17 19:15:20.382 | /home/jenkins/workspace/gate-bandit-integration-oslo.vmware/openstack/bandit
2016-02-17 19:15:20.382 | + [[ 0 -eq 1 ]]
2016-02-17 19:15:20.382 | ___________________________________ summary ____________________________________
2016-02-17 19:15:20.382 | integration: commands succeeded
2016-02-17 19:15:20.382 | congratulations :)
Running Bandit, erroneously, in the following way produces strange output:
MacBook-Pro:bandit travismcpeak$ bandit examples/multiline-str.py -3
Run started:
2015-03-20 18:23:40.705354
Files in scope (2):
-3 (score: 10)
Files excluded (0):
Files skipped (1):
-3 (No such file or directory)
Test results:
This is wrong because:
The hard-coded /tmp plugin doesn't handle multi-line strings very well. Maybe some code could be borrowed from the SQL injection plugin.
In this example, only lines 1 and 3 are in the report. Line 2, with "/tmp" itself, is missing:
x = """
/tmp
"""
In this example, only line 4 (the closing """) is emitted in the report:
def f():
"""
/tmp
"""
The hard-coded /tmp plugin doesn't handle multi-line strings very well. Maybe some code could be borrowed from the SQL injection plugin.
In this example, only lines 1 and 3 are in the report. Line 2, with "/tmp" itself, is missing:
x = """
/tmp
"""
In this example, only line 4 (the closing """) is emitted in the report:
def f():
"""
/tmp
"""
When running against Keystone with the Keystone profile file (-c bandit.yaml -p gate) we get a ton of errors like:
[tester] ERROR Bandit internal error running: blacklist on file /Users/travismcpeak/Documents/projects/OpenStack_projects/keystone/keystone/common/clean.py at line 67: 'qualnames'Traceback (most recent call last):
File "/Users/travismcpeak/Documents/projects/bandit/bandit/core/tester.py", line 62, in run_tests
result = test(context, test._config)
File "/Users/travismcpeak/Documents/projects/bandit/bandit/core/blacklisting.py", line 48, in blacklist
for qn in check['qualnames']:
KeyError: 'qualnames'
Consider the following test file:
import subprocess
my_val = 'do_something; ' + evil_value
subprocess.Popen(my_val, shell=True)
This is obviously a high risk command injection issue, but Bandit currently only reports a low. Since all we can tell is that it's a dynamically constructed string we have to assume HIGH severity IMO.
Patch https://review.openstack.org/#/c/278720 attempts to change test-requirements import of mock to be conditional for only 3.2 and lower. But the mock namespace in py34 is "unittest.mock" not just "mock" So this patch breaks on failing imports:
2016-02-10 23:35:34.138 | Failed to import test module: tests.unit.formatters.test_text
2016-02-10 23:35:34.138 | Traceback (most recent call last):
2016-02-10 23:35:34.138 | File "/home/jenkins/workspace/gate-bandit-python34/.tox/py34/lib/python3.4/site-packages/unittest2/loader.py", line 456, in _find_test_path
2016-02-10 23:35:34.138 | module = self._get_module_from_name(name)
2016-02-10 23:35:34.138 | File "/home/jenkins/workspace/gate-bandit-python34/.tox/py34/lib/python3.4/site-packages/unittest2/loader.py", line 395, in _get_module_from_name
2016-02-10 23:35:34.138 | import(name)
2016-02-10 23:35:34.139 | File "/home/jenkins/workspace/gate-bandit-python34/tests/unit/formatters/test_text.py", line 20, in
2016-02-10 23:35:34.139 | import mock
2016-02-10 23:35:34.139 | ImportError: No module named 'mock'
PoC code:
class InnoBackupEx(base.BackupRunner):
"""Implementation of Backup Strategy for InnoBackupEx."""
strategy_name = 'innobackupex'
@property
def cmd(self):
cmd = ('sudo innobackupex'
' --stream=xbstream'
' %(extra_opts)s'
' /var/lib/mysql 2>/tmp/innobackupex.log'
)
return cmd + self.zip_cmd + self.encrypt_cmd
Run Bandit against this code, it reports:
Issue: Probable insecure usage of temp file/directory.
Severity: Medium Confidence: Medium
Location: examples/line_no_test.py:7
6 def cmd(self):
7 cmd = ('sudo innobackupex'
8 ' --stream=xbstream'
The actual issue is on line 10.
When running against Keystone with the Keystone profile file (-c bandit.yaml -p gate) we get a ton of errors like:
[tester] ERROR Bandit internal error running: blacklist on file /Users/travismcpeak/Documents/projects/OpenStack_projects/keystone/keystone/common/clean.py at line 67: 'qualnames'Traceback (most recent call last):
File "/Users/travismcpeak/Documents/projects/bandit/bandit/core/tester.py", line 62, in run_tests
result = test(context, test._config)
File "/Users/travismcpeak/Documents/projects/bandit/bandit/core/blacklisting.py", line 48, in blacklist
for qn in check['qualnames']:
KeyError: 'qualnames'
The latest bandit (from source) is showing traceback errors from the hardcoded_sql_expressions plugin.
To recreate:
git clone https://github.com/openstack/bandit.git
git clone https://github.com/openstack/nova.git
cd bandit
tox -e py27
.tox/py27/bin/bandit -r ../nova/nova -n 5
jenkins@wdc-ecostack-dhcp-4-255:~/bandit$ .tox/py27/bin/bandit -r ../nova/nova -n 5
[bandit] INFO using config: /home/jenkins/bandit/bandit/config/bandit.yaml
[bandit] INFO running on Python 2.7.6
1418 [0.. /home/jenkins/bandit/bandit/plugins/general_hardcoded_password.py:41: UserWarning: Using relative path for word_list: ./wordlist/default-passwords
% word_list_path)
50.. 100.. 150.. 200.. 250.. 300.. 350.. [tester] ERROR Bandit internal error running: hardcoded_sql_expressions on file ../nova/nova/db/sqlalchemy/api.py at line 2170: 'Call' object has no attribute 'id'Traceback (most recent call last):
File "/home/jenkins/bandit/bandit/core/tester.py", line 65, in run_tests
result = test(context)
File "/home/jenkins/bandit/bandit/plugins/injection_sql.py", line 46, in hardcoded_sql_expressions
val = _evaluate_ast(context.node)
File "/home/jenkins/bandit/bandit/plugins/injection_sql.py", line 39, in _evaluate_ast
name = utils.get_called_name(out[0].parent)
File "/home/jenkins/bandit/bandit/core/utils.py", line 343, in get_called_name
return (func.attr if isinstance(func, ast.Attribute) else func.id)
AttributeError: 'Call' object has no attribute 'id'
[tester] ERROR Bandit internal error running: hardcoded_sql_expressions on file ../nova/nova/db/sqlalchemy/api.py at line 2170: 'Call' object has no attribute 'id'Traceback (most recent call last):
File "/home/jenkins/bandit/bandit/core/tester.py", line 65, in run_tests
result = test(context)
File "/home/jenkins/bandit/bandit/plugins/injection_sql.py", line 46, in hardcoded_sql_expressions
val = _evaluate_ast(context.node)
File "/home/jenkins/bandit/bandit/plugins/injection_sql.py", line 39, in _evaluate_ast
name = utils.get_called_name(out[0].parent)
File "/home/jenkins/bandit/bandit/core/utils.py", line 343, in get_called_name
return (func.attr if isinstance(func, ast.Attribute) else func.id)
AttributeError: 'Call' object has no attribute 'id'
Steps to reproduce:
Actual result:
The result contains report from test "assert_used":
Issue: [assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Severity: Low Confidence: High
Location: /home/ykotko/FRESH-FUEL_MAIN/fuel-qa/fuelweb_test/models/fuel_web_client.py:1878
1877 else:
1878 assert 'No cluster_deletion task found!'
1879
Running Bandit with -v (verbose mode) causes a traceback:
MacBook-Pro:bandit_json_bug travismcpeak$ bandit -v test_file2.py
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
[node_visitor] INFO Unable to find qualified name for module: test_file2.py
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 267, in main
args.output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 174, in output_results
lines=lines, out_format=output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/formatters/text.py", line 67, in report
manager.scores)):
TypeError: sum_scores() takes exactly 2 arguments (1 given)
Steps to reproduce:
Actual result:
The result contains report from test "assert_used":
Issue: [assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.
Severity: Low Confidence: High
Location: /home/ykotko/FRESH-FUEL_MAIN/fuel-qa/fuelweb_test/models/fuel_web_client.py:1878
1877 else:
1878 assert 'No cluster_deletion task found!'
1879
PoC code:
class InnoBackupEx(base.BackupRunner):
"""Implementation of Backup Strategy for InnoBackupEx."""
strategy_name = 'innobackupex'
@property
def cmd(self):
cmd = ('sudo innobackupex'
' --stream=xbstream'
' %(extra_opts)s'
' /var/lib/mysql 2>/tmp/innobackupex.log'
)
return cmd + self.zip_cmd + self.encrypt_cmd
Run Bandit against this code, it reports:
Issue: Probable insecure usage of temp file/directory.
Severity: Medium Confidence: Medium
Location: examples/line_no_test.py:7
6 def cmd(self):
7 cmd = ('sudo innobackupex'
8 ' --stream=xbstream'
The actual issue is on line 10.
When running against the nonsense example, we get a traceback:
MacBook-Pro:bandit travismcpeak$ bandit examples/nonsense.py
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 267, in main
args.output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 174, in output_results
lines=lines, out_format=output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/formatters/text.py", line 95, in report
rank)]
KeyError: 'SEVERITY.UNDEFINED'
Given it's by definition a nonsense Python file, we still need to handle the situation gracefully.
As a developer I just want to point bandit at my directory and have it go. Having to use find + xargs or shell expansion shouldn't be necessary.
When using the "-a vuln" option for the bandit command line, I get a KeyError.
promd-1s-dhcp317:bandit browne$ bandit -r ../glance/glance/ -a vuln
315 [0.. 50.. 100.. 150.. 200.. 250.. 300.. ]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/Library/Python/2.7/site-packages/bandit/bandit.py", line 88, in main
args.output_format)
File "/Library/Python/2.7/site-packages/bandit/core/manager.py", line 112, in output_results
output_format=output_format
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 382, in report
level=level) # noqa
File "/Library/Python/2.7/site-packages/bandit/core/result_store.py", line 324, in report_tty
issue['lineno'],
KeyError: 'lineno'
Running Bandit with -v (verbose mode) causes a traceback:
MacBook-Pro:bandit_json_bug travismcpeak$ bandit -v test_file2.py
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
[node_visitor] INFO Unable to find qualified name for module: test_file2.py
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 267, in main
args.output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 174, in output_results
lines=lines, out_format=output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/formatters/text.py", line 67, in report
manager.scores)):
TypeError: sum_scores() takes exactly 2 arguments (1 given)
If the baseline feature is used along with severity filtering the results end up broken.
Basically, the current baseline routine is to check if there are different results in the currently checked file than what is present in the baseline. If so, all the issues from the current file are inputted and then filtered. To make this clear let's say we have original file a.py:
import subprocess
do_something_benign()
os.system('/tmp/something_bad')
We'll get a low severity finding for subprocess usage, but if we examine this file with a -ll filter, this will be suppressed from the baseline output. We also get a higher severity error which for /tmp.
Now we run a baseline comparison against it, the first action that is performed is checking the results against the previous level. Since the previous level had the LOW severity finding filtered out, it only has the MEDIUM. Since no filtering has been done yet, the current version of the file includes the low severity issue. Basically the baseline has the low severity issue filtered out and the current version doesn't. So they don't match and all of the issues from the file get added to the results.
At this point filtering is done so the LOW severity issue is removed, but the point is even though nothing changed in this file Bandit thinks it did.
The correct behavior is to filter severity first.
When running Bandit with a typo I got a traceback:
MacBook-Pro:~ travismcpeak$ bandit 0
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 267, in main
args.output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 174, in output_results
lines=lines, out_format=output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/formatters/text.py", line 84, in report
label, manager.metrics.data['_totals'][metric]
KeyError: 'loc'
Whatever is going on here we should be more graceful about it.
When running bandit without the '-c' parameter, it has the inability to find bandit.yaml within a virtualenv.
[bandit] ERROR no config found - tried: ./bandit.yaml, /home/ericwb/.config/bandit/bandit.yaml, /etc/bandit/bandit.yaml, /usr/local/etc/bandit/bandit.yaml
To recreate:
ericwb@ericwb-virtual-machine:~/bandit$ .tox/py27/bin/bandit -c bandit/config/bandit.yaml -r examples/
Traceback (most recent call last):
File ".tox/py27/bin/bandit", line 10, in
sys.exit(main())
File "/home/ericwb/bandit/bandit/bandit.py", line 189, in main
verbose=args.verbose)
File "/home/ericwb/bandit/bandit/core/manager.py", line 55, in init
self.logger = self._init_logger(debug, log_format=log_format)
AttributeError: BanditManager instance has no attribute '_init_logger'
Currently, linerange_fix takes ~40% of bandit runtime, because it walks the ast down on almost every node. There are places where a few percent could be stripped, but the whole linerange / linerange_fix should be redesigned in the future.
Bandit freezes when start it with key -r against directory with init.py file
Steps to reproduce:
Actual result it is freezes on checking init.py file
The output of executing:
/tests/sec_scan$ ls
base.py init.py
/tests/sec_scan$ cat base.py
try:
from unittest.case import TestCase
except ImportError:
# Runing unit-tests in production environment
from unittest2.case import TestCase
from mock import patch
import logging
import os
import shutil
import subprocess
import sys
import tempfile
logging.basicConfig(stream=sys.stderr)
log = logging.getLogger("CliTest.ExecutionLog")
log.setLevel(logging.DEBUG)
class CliExectutionResult:
def init(self, process_handle, out, err):
self.return_code = process_handle.returncode
self.stdout = out
self.stderr = err
/tests/sec_scan$ cat init.py
(fuel-devops-venv)ykotko@ykotko-pc:~/FRESH-FUEL_MAIN/fuel-main/python-fuelclient/fuelclient/tests$ bandit -r sec_scan/
[bandit] INFO using config: /home/ykotko/FRESH-FUEL_MAIN/fuel-qa/fuel-devops-venv/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.6
----FREEZES---
/tests$ bandit -r sec_scan/
[bandit] INFO using config: /home/ykotko/FRESH-FUEL_MAIN/fuel-qa/fuel-devops-venv/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.6
Run started:
2016-01-27 15:32:40.661932
Run metrics:
Total lines of code: 19
Total lines skipped (#nosec): 0
Total issues (by severity):
Undefined: 0
Low: 1
Medium: 0
High: 0
Total issues (by confidence):
Undefined: 0
Low: 0
Medium: 0
High: 1
Files skipped (0):
Test results:
Issue: [blacklist_imports] Consider possible security implications associated with subprocess module.
Severity: Low Confidence: High
Location: sec_scan/base.py:13
12 import shutil
13 import subprocess
14 import sys
When running Bandit on setup.py (from its own directory) there is an uncaught exception:
(band)MacBook-Pro:bandit travismcpeak$ bandit -n 5 setup.py
Traceback (most recent call last):
File "/Users/travismcpeak/Documents/projects/bandit/band/bin/bandit", line 10, in
sys.exit(main())
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/bandit.py", line 74, in main
b_mgr.run_scope(args.files)
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/manager.py", line 134, in run_scope
self.b_rs, self.b_ts
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/manager.py", line 170, in _execute_ast_visitor
fname, self.logger, self.b_conf, b_ma, b_rs, b_ts, self.debug
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/node_visitor.py", line 60, in init
self.namespace = b_utils.get_module_qualname_from_path(fname)
File "/Users/travismcpeak/Documents/projects/bandit/band/lib/python2.7/site-packages/bandit/core/utils.py", line 134, in get_module_qualname_from_path
' Missing path or file name' % (path))
bandit.core.utils.InvalidModulePath: Invalid python file path: "setup.py" Missing path or file name
We should catch the exception and generate some sort of meaningful warning/log output based on it.
Bandit's JSON report doesn't exclude lines marked #nosec. The JSON report also doesn't respect the -l
CLI flag, which only shows higher-severity issues in the text report. The command bandit -f json -lll examples/skip.py
demonstrates both issues.
As an aside, perhaps #nosec lines shouldn't be scored at all. Right now it's up to the individual reports to filter out these lines. That's the reason tests/test_functional:FunctionalTests.test_skip
is skipped right now: #nosec lines receive a score.
A bug was introduced in a refactor that causes bandit to fail summing results after processing.
Issue: subprocess call - check for execution of untrusted input.
Severity: Low Confidence: High
Location: /Users/travismcpeak/Documents/projects/OpenStack_projects/keystone/tools/install_venv_common.py:64
63
64 proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
65 output = proc.communicate()[0]
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 243, in main
conf_filter=args.confidence - 1) > 0:
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 95, in results_count
return sum(i.filter(sev_filter, conf_filter) for i in self.results)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 95, in
return sum(i.filter(sev_filter, conf_filter) for i in self.results)
File "/usr/local/lib/python2.7/site-packages/bandit/core/issue.py", line 50, in filter
return (rank.index(self.severity) >= rank.index(severity) and
ValueError: 0 is not in list
If the baseline feature is used along with severity filtering the results end up broken.
Basically, the current baseline routine is to check if there are different results in the currently checked file than what is present in the baseline. If so, all the issues from the current file are inputted and then filtered. To make this clear let's say we have original file a.py:
import subprocess
do_something_benign()
os.system('/tmp/something_bad')
We'll get a low severity finding for subprocess usage, but if we examine this file with a -ll filter, this will be suppressed from the baseline output. We also get a higher severity error which for /tmp.
Now we run a baseline comparison against it, the first action that is performed is checking the results against the previous level. Since the previous level had the LOW severity finding filtered out, it only has the MEDIUM. Since no filtering has been done yet, the current version of the file includes the low severity issue. Basically the baseline has the low severity issue filtered out and the current version doesn't. So they don't match and all of the issues from the file get added to the results.
At this point filtering is done so the LOW severity issue is removed, but the point is even though nothing changed in this file Bandit thinks it did.
The correct behavior is to filter severity first.
Using --number with lines less than 3 will correctly trim output. For example:
bandit -r --number 1 glances/glances/
Issue: Try, Except, Pass detected.
Severity: Low Confidence: High
Location: glances/glances/plugins/glances_sensors.py:26
26 except ImportError:
Issue: Try, Except, Pass detected.
Severity: Low Confidence: High
Location: glances/glances/plugins/glances_uptime.py:76
76 except Exception:
However, using --number greater than 3 does not adjust the output. It still uses only 3 lines maximum.
bandit -r --number 10 glances/glances/
Issue: Try, Except, Pass detected.
Severity: Low Confidence: High
Location: glances/glances/plugins/glances_uptime.py:76
75 self.stats = str(timedelta(seconds=int(uptime) / 100))
76 except Exception:
77 pass
Running Bandit against the code:
subprocess.Popen('/bin/gcc --version', shell=True)
subprocess.Popen('/bin/gcc --version', shell='True')
.. results in two issues being flagged.
The check in plugins/injection_shell.py is essentially made up of the line:
if context.check_call_arg_value('shell', 'True'):
..
This implies that it is checking for a string rather than a boolean. I believe this should only flag an issue where the True bool is being used, rather than the string 'True'?
$ bandit examples/broken.py -n 1
[bandit] INFO using config: /Users/finnigaj/repo/bandit/venv27/bin/../etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
Run started:
2015-10-12 20:46:14.772219
Files skipped (0):
Test results:
Issue: subprocess call with shell=True identified, security issue.
Severity: High Confidence: High
Location: examples/bah.py:1
1 subprocess.Popen('/bin/gcc --version', shell=True)
Issue: subprocess call with shell=True identified, security issue.
Severity: High Confidence: High
Location: examples/bah.py:2
2 subprocess.Popen('/bin/gcc --version', shell='True')
When installed with no other changes, bandit will not detect any plugins. Tests end successful, even though no checks are really run.
It's not obvious unless bandit is run with --help which does provide an empty list of loaded plugins: "The following plugin suites were discovered and loaded: []"
Main issue seems to be that plugins not listed as entry points will not be detected by stevedore.
When running against the nonsense example, we get a traceback:
MacBook-Pro:bandit travismcpeak$ bandit examples/nonsense.py
[bandit] INFO using config: /usr/local/etc/bandit/bandit.yaml
[bandit] INFO running on Python 2.7.10
Traceback (most recent call last):
File "/usr/local/bin/bandit", line 10, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bandit/bandit.py", line 267, in main
args.output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/core/manager.py", line 174, in output_results
lines=lines, out_format=output_format)
File "/usr/local/lib/python2.7/site-packages/bandit/formatters/text.py", line 95, in report
rank)]
KeyError: 'SEVERITY.UNDEFINED'
Given it's by definition a nonsense Python file, we still need to handle the situation gracefully.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.