Plugin to flag insecure hash functions created using hashlib.new()

Currently, insecure hash function usage by calling hashlib.md5()
is flagged in B303. But these hash functions can also be obtained using
hashlib.new(), by passing 'md4' or 'md5' as an argument. This plugin
checks such usage.

Change-Id: I8d368aea287e1287e5f638b48c4297d355037839
Closes-Bug: #1708582
This commit is contained in:
Rajath Agasthya 2017-09-15 18:25:55 -07:00
parent dab37aace4
commit a98519927b
5 changed files with 91 additions and 0 deletions

View File

@ -174,6 +174,7 @@ Usage::
B321 ftplib
B322 input
B323 unverified_context
B324 hashlib_new_insecure_functions
B401 import_telnetlib
B402 import_ftplib
B403 import_pickle

View File

@ -0,0 +1,63 @@
# -*- coding:utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
r"""
==========================================================================
B324: Test for use of insecure md4 and md5 hash functions in hashlib.new()
==========================================================================
This plugin checks for the usage of the insecure MD4 and MD5 hash functions
in ``hashlib.new`` function. The ``hashlib.new`` function provides the ability
to construct a new hashing object using the named algorithm. This can be used
to create insecure hash functions like MD4 and MD5 if they are passed as
algorithm names to this function.
This is similar to B303 blacklist check, except that this checks for insecure
hash functions created using ``hashlib.new`` function.
:Example:
>> Issue: [B324:hashlib_new] Use of insecure MD4 or MD5 hash function.
Severity: Medium Confidence: High
Location: examples/hashlib_new_insecure_funcs.py:3
2
3 md5_hash = hashlib.new('md5', string='test')
4 print(md5_hash)
.. versionadded:: 1.5.0
"""
import bandit
from bandit.core import test_properties as test
@test.test_id('B324')
@test.checks('Call')
def hashlib_new(context):
if isinstance(context.call_function_name_qual, str):
qualname_list = context.call_function_name_qual.split('.')
func = qualname_list[-1]
if 'hashlib' in qualname_list and func == 'new':
args = context.call_args
keywords = context.call_keywords
name = args[0] if args else keywords['name']
if name.lower() in ('md4', 'md5'):
return bandit.Issue(
severity=bandit.MEDIUM,
confidence=bandit.HIGH,
text="Use of insecure MD4 or MD5 hash function.",
lineno=context.node.lineno,
)

View File

@ -0,0 +1,16 @@
import hashlib
hashlib.new('md5')
hashlib.new('md4', 'test')
hashlib.new(name='md5', string='test')
hashlib.new('MD4', string='test')
hashlib.new(string='test', name='MD5')
# Test that plugin does not flag valid hash functions.
hashlib.new('sha256')
hashlib.new('SHA512')

View File

@ -81,6 +81,9 @@ bandit.plugins =
# bandit/plugins/injection_sql.py
hardcoded_sql_expressions = bandit.plugins.injection_sql:hardcoded_sql_expressions
# bandit/plugins/hashlib_new_insecure_functions.py
hashlib_new_insecure_functions = bandit.plugins.hashlib_new_insecure_functions:hashlib_new
# bandit/plugins/injection_wildcard.py
linux_commands_wildcard_injection = bandit.plugins.injection_wildcard:linux_commands_wildcard_injection

View File

@ -697,3 +697,11 @@ class FunctionalTests(testtools.TestCase):
'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 0, 'HIGH': 1}
}
self.check_example('unverified_context.py', expect)
def test_hashlib_new_insecure_functions(self):
'''Test insecure hash functions created by `hashlib.new`.'''
expect = {
'SEVERITY': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 5, 'HIGH': 0},
'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 0, 'HIGH': 5}
}
self.check_example('hashlib_new_insecure_functions.py', expect)