Add check for secret=True on oslo password options

Anywhere oslo.config is used to register an option for a password,
Bandit needs to check whether its marked secret.

https://github.com/hyakuhei/OSSG-Security-Practices/blob/master/sensitive_config_file_options.md

Change-Id: I77ed0d50e004c41a685dac5c647b2129de8bc198
This commit is contained in:
Eric Brown 2015-02-24 18:01:42 -08:00
parent 7d0ff36257
commit 8972342d0b
5 changed files with 78 additions and 1 deletions

View File

@ -108,3 +108,8 @@ ssl_with_bad_version:
- 'PROTOCOL_TLSv1' # strict option
- 'SSLv3_METHOD' # strict option
- 'TLSv1_METHOD' # strict option
password_config_option_not_marked_secret:
function_names:
- oslo.config.cfg.StrOpt
- oslo_config.cfg.StrOpt

View File

@ -65,4 +65,4 @@ CONFIDENCE_LEVEL = confidence_namedtuple(HIGH=10, MEDIUM=5, LOW=0)
# These are only useful when we have a constant in code. If we
# have a variable we cannot determine if False.
# See https://docs.python.org/2/library/stdtypes.html#truth-value-testing
FALSE_VALUES = (None, False, 0, 0L, 0.0, 0j, '', (), [], {})
FALSE_VALUES = (None, False, 'False', 0, 0L, 0.0, 0j, '', (), [], {})

View File

@ -0,0 +1,36 @@
# Copyright (c) 2015 VMware, Inc.
#
# 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.
import bandit
from bandit.core.test_properties import *
@takes_config
@checks('Call')
def password_config_option_not_marked_secret(context, config):
if (context.call_function_name_qual in config['function_names']):
if context.get_call_arg_at_position(0).endswith('password'):
# Checks whether secret=False or secret is not set (None).
if (context.check_call_arg_value('secret') in
constants.FALSE_VALUES):
return(bandit.WARN, 'oslo config option not marked secret=True'
' identified, security issue. %s' %
context.call_args_string)
# Checks whether secret is not True, for example when its set to a
# variable, secret=secret.
elif context.check_call_arg_value('secret') != 'True':
return(bandit.INFO, 'oslo config option possibly not marked'
' secret=True identified. %s' %
context.call_args_string)

View File

@ -0,0 +1,28 @@
from oslo_config import cfg
# Correct
secret = True
opts = [
cfg.StrOpt('admin_user',
help="User's name"),
cfg.StrOpt('admin_password',
secret=True,
help="User's password"),
cfg.StrOpt('nova_password',
secret=secret,
help="Nova user password"),
]
# Incorrect: password not marked secret
ldap_opts = [
cfg.StrOpt('ldap_user',
help="LDAP ubind ser name"),
cfg.StrOpt('ldap_password',
help="LDAP bind user password"),
cfg.StrOpt('ldap_password_attribute',
help="LDAP password attribute (default userPassword"),
cfg.StrOpt('user_password',
secret=False,
help="User password"),
]

View File

@ -19,6 +19,7 @@ import os
import unittest
import inspect
from bandit.core import constants as C
from bandit.core import manager as b_manager
from bandit.core import test_set as b_test_set
@ -284,3 +285,10 @@ class FunctionalTests(unittest.TestCase):
self.b_mgr.run_tests()
self.assertEqual(4, self.b_mgr.results_count)
self.assertEqual(35, self.b_mgr.scores[0])
def test_secret_config_option(self):
path = os.path.join(os.getcwd(), 'examples', 'secret-config-option.py')
self.b_mgr.discover_files([path], True)
self.b_mgr.run_tests()
expected = 2 * C.SEVERITY_VALUES['WARN'] + C.SEVERITY_VALUES['INFO']
self.assertEqual(expected, self.b_mgr.scores[0])