diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 8b87fce8f..000000000 --- a/.coveragerc +++ /dev/null @@ -1,3 +0,0 @@ -[report] -include = bandit/* -omit = bandit/tests/functional/* diff --git a/bandit/plugins/snmp_security_check.py b/bandit/plugins/snmp_security_check.py new file mode 100644 index 000000000..02308bd81 --- /dev/null +++ b/bandit/plugins/snmp_security_check.py @@ -0,0 +1,69 @@ +# +# Copyright (c) 2018 SolarWinds, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +import bandit +from bandit.core import test_properties as test + + +@test.checks("Call") +@test.test_id("B508") +def snmp_insecure_version_check(context): + """**B508: Checking for insecure SNMP versions** + + This test is for checking for the usage of insecure SNMP version like + v1, v2c + + Using the pysnmp documentation: + http://snmplabs.com/pysnmp/examples/hlapi/asyncore/sync/manager/cmdgen/snmp-versions.html + + Please update your code to use more secure versions of SNMP. + + .. versionadded:: 1.7.2 + """ + + if context.call_function_name_qual == "CommunityData": + # We called community data. Lets check our args + if context.check_call_arg_value( + "mpModel", 0 + ) or context.check_call_arg_value("mpModel", 1): + return bandit.Issue( + severity=bandit.MEDIUM, + confidence=bandit.HIGH, + text="The use of SNMPv1 and SNMPv2 is insecure. " + "You should use SNMPv3 if able.", + lineno=context.get_lineno_for_call_arg("CommunityData"), + ) + + +@test.checks("Call") +@test.test_id("B509") +def snmp_crypto_check(context): + """**B509: Checking for weak cryptography** + + This test is for checking for the usage of insecure SNMP cryptography: + v3 using noAuthNoPriv. + + Using the pysnmp documentation: + http://snmplabs.com/pysnmp/examples/hlapi/asyncore/sync/manager/cmdgen/snmp-versions.html + + Please update your code to use more secure versions of SNMP. For example: + + Instead of: + `CommunityData('public', mpModel=0)` + + Use (Defaults to usmHMACMD5AuthProtocol and usmDESPrivProtocol + `UsmUserData("securityName", "authName", "privName")` + + .. versionadded:: 1.7.2 + """ + + if context.call_function_name_qual == "UsmUserData": + if context.call_args_count < 3: + return bandit.Issue( + severity=bandit.MEDIUM, + confidence=bandit.HIGH, + text="You should not use SNMPv3 without encryption. " + "noAuthNoPriv & authNoPriv is insecure", + lineno=context.get_lineno_for_call_arg("UsmUserData"), + ) diff --git a/doc/source/plugins/b508_snmp_insecure_version.rst b/doc/source/plugins/b508_snmp_insecure_version.rst new file mode 100644 index 000000000..e3bf6afa3 --- /dev/null +++ b/doc/source/plugins/b508_snmp_insecure_version.rst @@ -0,0 +1,8 @@ +--------------------------- +B508: snmp_insecure_version +--------------------------- + +.. currentmodule:: bandit.plugins.snmp_security_check + +.. autofunction:: snmp_insecure_version_check + :noindex: \ No newline at end of file diff --git a/doc/source/plugins/b508_snmp_weak_cryptography.rst b/doc/source/plugins/b508_snmp_weak_cryptography.rst new file mode 100644 index 000000000..2c838d474 --- /dev/null +++ b/doc/source/plugins/b508_snmp_weak_cryptography.rst @@ -0,0 +1,8 @@ +---------------------------- +B509: snmp_weak_cryptography +---------------------------- + +.. currentmodule:: bandit.plugins.snmp_security_check + +.. autofunction:: snmp_crypto_check + :noindex: diff --git a/examples/snmp.py b/examples/snmp.py new file mode 100644 index 000000000..a24a90b9b --- /dev/null +++ b/examples/snmp.py @@ -0,0 +1,10 @@ +from pysnmp.hlapi import CommunityData, UsmUserData + +# SHOULD FAIL +a = CommunityData('public', mpModel=0) +# SHOULD FAIL +insecure = UsmUserData("securityName") +# SHOULD FAIL +auth_no_priv = UsmUserData("securityName","authName") +# SHOULD PASS +less_insecure = UsmUserData("securityName","authName","privName") diff --git a/setup.cfg b/setup.cfg index 4ed4beb3e..392061827 100644 --- a/setup.cfg +++ b/setup.cfg @@ -129,6 +129,10 @@ bandit.plugins = # bandit/plugins/ssh_no_host_key_verification.py ssh_no_host_key_verification = bandit.plugins.ssh_no_host_key_verification:ssh_no_host_key_verification + # bandit/plugins/snmp_security_check.py + snmp_insecure_version = bandit.plugins.snmp_security_check:snmp_insecure_version_check + snmp_weak_cryptography = bandit.plugins.snmp_security_check:snmp_crypto_check + [build_sphinx] all_files = 1 build-dir = doc/build