From daad38475fbb96b5180b957385d3cfdc43468db0 Mon Sep 17 00:00:00 2001 From: XIANJUN ZHU Date: Thu, 3 Oct 2019 08:55:17 -0400 Subject: [PATCH 1/8] feat: support ibm cos hmac * feat: support ibm cos hmac * feat: extract common patterns * feat: more coverage * feat: more coverage * fix: broken build * feat: more detailed tests * fix: more test cases based on comment * fix: more test cases * fix: more test cases --- ibm_cos_hmac.py | 154 +++++++++++++++++++++++++++++++++++++ ibm_cos_hmac_test.py | 176 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 330 insertions(+) create mode 100644 ibm_cos_hmac.py create mode 100644 ibm_cos_hmac_test.py diff --git a/ibm_cos_hmac.py b/ibm_cos_hmac.py new file mode 100644 index 000000000..c90b45b9f --- /dev/null +++ b/ibm_cos_hmac.py @@ -0,0 +1,154 @@ +from __future__ import absolute_import + +import datetime +import hashlib +import hmac + +import requests + +from .base import RegexBasedDetector +from detect_secrets.core.constants import VerifiedResult + + +class IBMCosHmacDetector(RegexBasedDetector): + # requires 3 factors + # + # access_key: access_key_id + # secret_key: secret_access_key + # host, defaults to 's3.us.cloud-object-storage.appdomain.cloud' + + secret_type = 'IBM COS HMAC Credentials' + + token_prefix = r'(?:(?:ibm)?[-_]?cos[-_]?(?:hmac)?|)' + password_keyword = r'(?:secret[-_]?(?:access)?[-_]?key)' + password = r'[a-f0-9]{48}' + denylist = ( + RegexBasedDetector.assign_regex_generator( + prefix_regex=token_prefix, + password_keyword_regex=password_keyword, + password_regex=password, + ), + ) + + def get_access_key_id(self, content): + key_id_keyword_regex = r'(?:access(?:_|-|)(?:key|)(?:_|-|)id|key(?:_|-|)id)' + key_id_regex = r'([a-f0-9]{32})' + + regex = RegexBasedDetector.assign_regex_generator( + prefix_regex=self.token_prefix, + password_keyword_regex=key_id_keyword_regex, + password_regex=key_id_regex, + ) + + return [ + match + for line in content.splitlines() + for match in regex.findall(line) + ] + + def verify(self, token, content, potential_secret=None): + + key_id_matches = self.get_access_key_id(content) + + if not key_id_matches: + return VerifiedResult.UNVERIFIED + + try: + for key_id in key_id_matches: + verify_result = verify_ibm_cos_hmac_credentials( + key_id, token, + ) + if verify_result is True: + potential_secret.other_factors['access_key_id'] = key_id + return VerifiedResult.VERIFIED_TRUE + except Exception: + return VerifiedResult.UNVERIFIED + + return VerifiedResult.VERIFIED_FALSE + + +def hash(key, msg): + return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest() + + +def createSignatureKey(key, datestamp, region, service): + + keyDate = hash(('AWS4' + key).encode('utf-8'), datestamp) + keyString = hash(keyDate, region) + keyService = hash(keyString, service) + keySigning = hash(keyService, 'aws4_request') + return keySigning + + +def verify_ibm_cos_hmac_credentials( + access_key, + secret_key, + host='s3.us.cloud-object-storage.appdomain.cloud', +): + # Sample code referenced from link below + # https://cloud.ibm.com/docs/services/cloud-object-storage/api-reference?topic=cloud-object-storage-hmac-signature # noqa: E501 + + # request elements + http_method = 'GET' + # region is a wildcard value that takes the place of the AWS region value + # as COS doen't use the same conventions for regions, this parameter can accept any string + region = 'us-standard' + endpoint = 'https://{}'.format(host) + bucket = '' # add a '/' before the bucket name to list buckets + object_key = '' + request_parameters = '' + + # assemble the standardized request + time = datetime.datetime.utcnow() + timestamp = time.strftime('%Y%m%dT%H%M%SZ') + datestamp = time.strftime('%Y%m%d') + + standardized_resource = '/' + bucket + '/' + object_key + standardized_querystring = request_parameters + standardized_headers = 'host:' + host + '\n' + 'x-amz-date:' + timestamp + '\n' + signed_headers = 'host;x-amz-date' + payload_hash = hashlib.sha256(''.encode('utf-8')).hexdigest() + + standardized_request = ( + http_method + '\n' + + standardized_resource + '\n' + + standardized_querystring + '\n' + + standardized_headers + '\n' + + signed_headers + '\n' + + payload_hash + ).encode('utf-8') + + # assemble string-to-sign + hashing_algorithm = 'AWS4-HMAC-SHA256' + credential_scope = datestamp + '/' + region + '/' + 's3' + '/' + 'aws4_request' + sts = ( + hashing_algorithm + '\n' + + timestamp + '\n' + + credential_scope + '\n' + + hashlib.sha256(standardized_request).hexdigest() + ) + + # generate the signature + signature_key = createSignatureKey(secret_key, datestamp, region, 's3') + signature = hmac.new( + signature_key, + (sts).encode('utf-8'), + hashlib.sha256, + ).hexdigest() + + # assemble all elements into the 'authorization' header + v4auth_header = ( + hashing_algorithm + ' ' + + 'Credential=' + access_key + '/' + credential_scope + ', ' + + 'SignedHeaders=' + signed_headers + ', ' + + 'Signature=' + signature + ) + + # create and send the request + headers = {'x-amz-date': timestamp, 'Authorization': v4auth_header} + # the 'requests' package autmatically adds the required 'host' header + request_url = endpoint + standardized_resource + standardized_querystring + + request = requests.get(request_url, headers=headers) + + return request.status_code == 200 diff --git a/ibm_cos_hmac_test.py b/ibm_cos_hmac_test.py new file mode 100644 index 000000000..101658b3e --- /dev/null +++ b/ibm_cos_hmac_test.py @@ -0,0 +1,176 @@ +from __future__ import absolute_import + +import textwrap + +import pytest +import responses +from mock import patch + +from detect_secrets.core.constants import VerifiedResult +from detect_secrets.core.potential_secret import PotentialSecret +from detect_secrets.plugins.ibm_cos_hmac import IBMCosHmacDetector +from detect_secrets.plugins.ibm_cos_hmac import verify_ibm_cos_hmac_credentials + + +ACCESS_KEY_ID = '1234567890abcdef1234567890abcdef' +SECRET_ACCESS_KEY = '1234567890abcdef1234567890abcdef1234567890abcdef' + + +class TestIBMCosHmacDetector(object): + + @pytest.mark.parametrize( + 'payload, should_flag', + [ + ('"secret_access_key": "1234567890abcdef1234567890abcdef1234567890abcdef"', True,), + ('secret_access_key=1234567890abcdef1234567890abcdef1234567890abcdef', True), + ('secret_access_key="1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('secret_access_key=\'1234567890abcdef1234567890abcdef1234567890abcdef\'', True), + ('secret_access_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ( + 'COS_HMAC_SECRET_ACCESS_KEY = "1234567890abcdef1234567890abcdef1234567890abcdef"', + True, + ), + ( + 'ibm_cos_SECRET_ACCESS_KEY = "1234567890abcdef1234567890abcdef1234567890abcdef"', + True, + ), + ( + 'ibm_cos_secret_access_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', + True, + ), + ('ibm_cos_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('cos_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('ibm-cos_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('cos-hmac_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('coshmac_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('ibmcoshmac_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('ibmcos_secret_key = "1234567890abcdef1234567890abcdef1234567890abcdef"', True), + ('not_secret = notapassword', False), + ('someotherpassword = "doesnt start right"', False), + ], + ) + def test_analyze_string(self, payload, should_flag): + logic = IBMCosHmacDetector() + + output = logic.analyze_string(payload, 1, 'mock_filename') + assert len(output) == int(should_flag) + + @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') + def test_verify_invalid_secret(self, mock_hmac_verify): + mock_hmac_verify.return_value = False + + potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) + assert IBMCosHmacDetector().verify( + SECRET_ACCESS_KEY, + '''access_key_id={}'''.format(ACCESS_KEY_ID), + potential_secret, + ) == VerifiedResult.VERIFIED_FALSE + + mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) + + @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') + def test_verify_valid_secret(self, mock_hmac_verify): + mock_hmac_verify.return_value = True + + potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) + assert IBMCosHmacDetector().verify( + SECRET_ACCESS_KEY, + '''access_key_id={}'''.format(ACCESS_KEY_ID), + potential_secret, + ) == VerifiedResult.VERIFIED_TRUE + + mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) + + @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') + def test_verify_unverified_secret(self, mock_hmac_verify): + mock_hmac_verify.side_effect = Exception('oops') + + potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) + assert IBMCosHmacDetector().verify( + SECRET_ACCESS_KEY, + '''access_key_id={}'''.format(ACCESS_KEY_ID), + potential_secret, + ) == VerifiedResult.UNVERIFIED + + mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) + + @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') + def test_verify_unverified_secret_no_match(self, mock_hmac_verify): + mock_hmac_verify.side_effect = Exception('oops') + + potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) + assert IBMCosHmacDetector().verify( + SECRET_ACCESS_KEY, + '''something={}'''.format(ACCESS_KEY_ID), + potential_secret, + ) == VerifiedResult.UNVERIFIED + + mock_hmac_verify.assert_not_called() + + @pytest.mark.parametrize( + 'content, expected_output', + ( + ( + textwrap.dedent(""" + access_key_id = {} + """)[1:-1].format( + ACCESS_KEY_ID, + ), + [ACCESS_KEY_ID], + ), + ( + 'access_key_id = {}'.format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + 'access-key-id := {}'.format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + "\"access_id\":\"{}\"".format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + "key_id = \"{}\"".format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + "key-id = '{}'".format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + "[\"access_key_id\"] = '{}'".format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), + ( + 'id = {}'.format(ACCESS_KEY_ID), + [], + ), + ), + ) + def test_get_access_key_id(self, content, expected_output): + assert IBMCosHmacDetector().get_access_key_id(content) == expected_output + + +@pytest.mark.parametrize( + 'status_code, validation_result', + [ + (200, True,), + (403, False,), + ], +) +@responses.activate +def test_verify_ibm_cos_hmac_credentials(status_code, validation_result): + host = 'fake.s3.us.cloud-object-storage.appdomain.cloud' + responses.add( + responses.GET, 'https://{}//'.format(host), + json={'some': 'thing'}, status=status_code, + ) + + assert verify_ibm_cos_hmac_credentials( + ACCESS_KEY_ID, SECRET_ACCESS_KEY, host, + ) is validation_result + assert len(responses.calls) == 1 + headers = responses.calls[0].request.headers + assert headers['Authorization'].startswith('AWS4-HMAC-SHA256') + assert headers['x-amz-date'] is not None From 50f5b86e9adc94cfa71314ab6960408a03135c11 Mon Sep 17 00:00:00 2001 From: XIANJUN ZHU Date: Thu, 3 Oct 2019 13:26:36 -0400 Subject: [PATCH 2/8] fix: extract common logic --- ibm_cos_hmac.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ibm_cos_hmac.py b/ibm_cos_hmac.py index c90b45b9f..e2c693a5d 100644 --- a/ibm_cos_hmac.py +++ b/ibm_cos_hmac.py @@ -84,6 +84,15 @@ def verify_ibm_cos_hmac_credentials( access_key, secret_key, host='s3.us.cloud-object-storage.appdomain.cloud', +): + response = query_ibm_cos_hmac(access_key, secret_key, host) + return response.status_code == 200 + + +def query_ibm_cos_hmac( + access_key, + secret_key, + host='s3.us.cloud-object-storage.appdomain.cloud', ): # Sample code referenced from link below # https://cloud.ibm.com/docs/services/cloud-object-storage/api-reference?topic=cloud-object-storage-hmac-signature # noqa: E501 @@ -151,4 +160,4 @@ def verify_ibm_cos_hmac_credentials( request = requests.get(request_url, headers=headers) - return request.status_code == 200 + return request From f60ad7867c86684913085993e7053470b0830f4f Mon Sep 17 00:00:00 2001 From: XIANJUN ZHU Date: Thu, 3 Oct 2019 14:14:40 -0400 Subject: [PATCH 3/8] Enable IBM Cos detector as default detector * feat: enable cos detector by default * feat: one more access key case --- ibm_cos_hmac.py | 4 ++-- ibm_cos_hmac_test.py | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ibm_cos_hmac.py b/ibm_cos_hmac.py index e2c693a5d..0f105c561 100644 --- a/ibm_cos_hmac.py +++ b/ibm_cos_hmac.py @@ -21,7 +21,7 @@ class IBMCosHmacDetector(RegexBasedDetector): token_prefix = r'(?:(?:ibm)?[-_]?cos[-_]?(?:hmac)?|)' password_keyword = r'(?:secret[-_]?(?:access)?[-_]?key)' - password = r'[a-f0-9]{48}' + password = r'([a-f0-9]{48})' denylist = ( RegexBasedDetector.assign_regex_generator( prefix_regex=token_prefix, @@ -31,7 +31,7 @@ class IBMCosHmacDetector(RegexBasedDetector): ) def get_access_key_id(self, content): - key_id_keyword_regex = r'(?:access(?:_|-|)(?:key|)(?:_|-|)id|key(?:_|-|)id)' + key_id_keyword_regex = r'(?:access[-_]?(?:key)?[-_]?(?:id)?|key[-_]?id)' key_id_regex = r'([a-f0-9]{32})' regex = RegexBasedDetector.assign_regex_generator( diff --git a/ibm_cos_hmac_test.py b/ibm_cos_hmac_test.py index 101658b3e..f01ed0b6e 100644 --- a/ibm_cos_hmac_test.py +++ b/ibm_cos_hmac_test.py @@ -21,7 +21,7 @@ class TestIBMCosHmacDetector(object): @pytest.mark.parametrize( 'payload, should_flag', [ - ('"secret_access_key": "1234567890abcdef1234567890abcdef1234567890abcdef"', True,), + ('"secret_access_key": "1234567890abcdef1234567890abcdef1234567890abcdef"', True), ('secret_access_key=1234567890abcdef1234567890abcdef1234567890abcdef', True), ('secret_access_key="1234567890abcdef1234567890abcdef1234567890abcdef"', True), ('secret_access_key=\'1234567890abcdef1234567890abcdef1234567890abcdef\'', True), @@ -138,6 +138,10 @@ def test_verify_unverified_secret_no_match(self, mock_hmac_verify): "key-id = '{}'".format(ACCESS_KEY_ID), [ACCESS_KEY_ID], ), + ( + "access_key = '{}'".format(ACCESS_KEY_ID), + [ACCESS_KEY_ID], + ), ( "[\"access_key_id\"] = '{}'".format(ACCESS_KEY_ID), [ACCESS_KEY_ID], @@ -155,8 +159,8 @@ def test_get_access_key_id(self, content, expected_output): @pytest.mark.parametrize( 'status_code, validation_result', [ - (200, True,), - (403, False,), + (200, True), + (403, False), ], ) @responses.activate From c9640c85ddffbca9062b9388f6d6fa00dd025827 Mon Sep 17 00:00:00 2001 From: XIANJUN ZHU Date: Thu, 10 Oct 2019 16:31:44 -0400 Subject: [PATCH 4/8] Use RegexBasedDetector.assign_regex_generator * feat: use assign regex in cloudant * feat: use assign regex in db2 * feat: use assign regex in gh * feat: use assign regex in iam * feat: use assign regex in sl * address comments * address comments * address comments --- ibm_cos_hmac.py | 36 ++++++++++++++++++------------------ ibm_cos_hmac_test.py | 5 +++-- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/ibm_cos_hmac.py b/ibm_cos_hmac.py index 0f105c561..68fd98fa7 100644 --- a/ibm_cos_hmac.py +++ b/ibm_cos_hmac.py @@ -30,25 +30,8 @@ class IBMCosHmacDetector(RegexBasedDetector): ), ) - def get_access_key_id(self, content): - key_id_keyword_regex = r'(?:access[-_]?(?:key)?[-_]?(?:id)?|key[-_]?id)' - key_id_regex = r'([a-f0-9]{32})' - - regex = RegexBasedDetector.assign_regex_generator( - prefix_regex=self.token_prefix, - password_keyword_regex=key_id_keyword_regex, - password_regex=key_id_regex, - ) - - return [ - match - for line in content.splitlines() - for match in regex.findall(line) - ] - def verify(self, token, content, potential_secret=None): - - key_id_matches = self.get_access_key_id(content) + key_id_matches = find_access_key_id(content) if not key_id_matches: return VerifiedResult.UNVERIFIED @@ -67,6 +50,23 @@ def verify(self, token, content, potential_secret=None): return VerifiedResult.VERIFIED_FALSE +def find_access_key_id(content): + key_id_keyword_regex = r'(?:access[-_]?(?:key)?[-_]?(?:id)?|key[-_]?id)' + key_id_regex = r'([a-f0-9]{32})' + + regex = RegexBasedDetector.assign_regex_generator( + prefix_regex=IBMCosHmacDetector.token_prefix, + password_keyword_regex=key_id_keyword_regex, + password_regex=key_id_regex, + ) + + return [ + match + for line in content.splitlines() + for match in regex.findall(line) + ] + + def hash(key, msg): return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest() diff --git a/ibm_cos_hmac_test.py b/ibm_cos_hmac_test.py index f01ed0b6e..0cf6a774b 100644 --- a/ibm_cos_hmac_test.py +++ b/ibm_cos_hmac_test.py @@ -8,6 +8,7 @@ from detect_secrets.core.constants import VerifiedResult from detect_secrets.core.potential_secret import PotentialSecret +from detect_secrets.plugins.ibm_cos_hmac import find_access_key_id from detect_secrets.plugins.ibm_cos_hmac import IBMCosHmacDetector from detect_secrets.plugins.ibm_cos_hmac import verify_ibm_cos_hmac_credentials @@ -152,8 +153,8 @@ def test_verify_unverified_secret_no_match(self, mock_hmac_verify): ), ), ) - def test_get_access_key_id(self, content, expected_output): - assert IBMCosHmacDetector().get_access_key_id(content) == expected_output + def test_find_access_key_id(self, content, expected_output): + assert find_access_key_id(content) == expected_output @pytest.mark.parametrize( From d82df7bcf68c444eb2786e3885595405ce6cbee7 Mon Sep 17 00:00:00 2001 From: Xianjun Zhu Date: Fri, 1 Nov 2019 15:22:26 -0400 Subject: [PATCH 5/8] Move files back --- ibm_cos_hmac.py => detect_secrets/plugins/ibm_cos_hmac.py | 0 ibm_cos_hmac_test.py => tests/plugins/ibm_cos_hmac_test.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename ibm_cos_hmac.py => detect_secrets/plugins/ibm_cos_hmac.py (100%) rename ibm_cos_hmac_test.py => tests/plugins/ibm_cos_hmac_test.py (100%) diff --git a/ibm_cos_hmac.py b/detect_secrets/plugins/ibm_cos_hmac.py similarity index 100% rename from ibm_cos_hmac.py rename to detect_secrets/plugins/ibm_cos_hmac.py diff --git a/ibm_cos_hmac_test.py b/tests/plugins/ibm_cos_hmac_test.py similarity index 100% rename from ibm_cos_hmac_test.py rename to tests/plugins/ibm_cos_hmac_test.py From 136a16e4ae28a01388299d09a495e080247444a4 Mon Sep 17 00:00:00 2001 From: Xianjun Zhu Date: Fri, 1 Nov 2019 15:30:09 -0400 Subject: [PATCH 6/8] fix tests --- detect_secrets/plugins/ibm_cos_hmac.py | 16 ++++++++-------- tests/plugins/ibm_cos_hmac_test.py | 25 ++++++++----------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/detect_secrets/plugins/ibm_cos_hmac.py b/detect_secrets/plugins/ibm_cos_hmac.py index 68fd98fa7..021a9f5da 100644 --- a/detect_secrets/plugins/ibm_cos_hmac.py +++ b/detect_secrets/plugins/ibm_cos_hmac.py @@ -10,7 +10,8 @@ from detect_secrets.core.constants import VerifiedResult -class IBMCosHmacDetector(RegexBasedDetector): +class IbmCosHmacDetector(RegexBasedDetector): + """Scans for IBM Cloud Object Storage HMAC credentials.""" # requires 3 factors # # access_key: access_key_id @@ -25,12 +26,12 @@ class IBMCosHmacDetector(RegexBasedDetector): denylist = ( RegexBasedDetector.assign_regex_generator( prefix_regex=token_prefix, - password_keyword_regex=password_keyword, - password_regex=password, + secret_keyword_regex=password_keyword, + secret_regex=password, ), ) - def verify(self, token, content, potential_secret=None): + def verify(self, token, content): key_id_matches = find_access_key_id(content) if not key_id_matches: @@ -42,7 +43,6 @@ def verify(self, token, content, potential_secret=None): key_id, token, ) if verify_result is True: - potential_secret.other_factors['access_key_id'] = key_id return VerifiedResult.VERIFIED_TRUE except Exception: return VerifiedResult.UNVERIFIED @@ -55,9 +55,9 @@ def find_access_key_id(content): key_id_regex = r'([a-f0-9]{32})' regex = RegexBasedDetector.assign_regex_generator( - prefix_regex=IBMCosHmacDetector.token_prefix, - password_keyword_regex=key_id_keyword_regex, - password_regex=key_id_regex, + prefix_regex=IbmCosHmacDetector.token_prefix, + secret_keyword_regex=key_id_keyword_regex, + secret_regex=key_id_regex, ) return [ diff --git a/tests/plugins/ibm_cos_hmac_test.py b/tests/plugins/ibm_cos_hmac_test.py index 0cf6a774b..91e71485d 100644 --- a/tests/plugins/ibm_cos_hmac_test.py +++ b/tests/plugins/ibm_cos_hmac_test.py @@ -7,9 +7,8 @@ from mock import patch from detect_secrets.core.constants import VerifiedResult -from detect_secrets.core.potential_secret import PotentialSecret from detect_secrets.plugins.ibm_cos_hmac import find_access_key_id -from detect_secrets.plugins.ibm_cos_hmac import IBMCosHmacDetector +from detect_secrets.plugins.ibm_cos_hmac import IbmCosHmacDetector from detect_secrets.plugins.ibm_cos_hmac import verify_ibm_cos_hmac_credentials @@ -17,7 +16,7 @@ SECRET_ACCESS_KEY = '1234567890abcdef1234567890abcdef1234567890abcdef' -class TestIBMCosHmacDetector(object): +class TestIbmCosHmacDetector(object): @pytest.mark.parametrize( 'payload, should_flag', @@ -51,20 +50,18 @@ class TestIBMCosHmacDetector(object): ], ) def test_analyze_string(self, payload, should_flag): - logic = IBMCosHmacDetector() + logic = IbmCosHmacDetector() - output = logic.analyze_string(payload, 1, 'mock_filename') + output = logic.analyze_line(payload, 1, 'mock_filename') assert len(output) == int(should_flag) @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') def test_verify_invalid_secret(self, mock_hmac_verify): mock_hmac_verify.return_value = False - potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) - assert IBMCosHmacDetector().verify( + assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, '''access_key_id={}'''.format(ACCESS_KEY_ID), - potential_secret, ) == VerifiedResult.VERIFIED_FALSE mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) @@ -73,11 +70,9 @@ def test_verify_invalid_secret(self, mock_hmac_verify): def test_verify_valid_secret(self, mock_hmac_verify): mock_hmac_verify.return_value = True - potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) - assert IBMCosHmacDetector().verify( + assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, '''access_key_id={}'''.format(ACCESS_KEY_ID), - potential_secret, ) == VerifiedResult.VERIFIED_TRUE mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) @@ -86,11 +81,9 @@ def test_verify_valid_secret(self, mock_hmac_verify): def test_verify_unverified_secret(self, mock_hmac_verify): mock_hmac_verify.side_effect = Exception('oops') - potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) - assert IBMCosHmacDetector().verify( + assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, '''access_key_id={}'''.format(ACCESS_KEY_ID), - potential_secret, ) == VerifiedResult.UNVERIFIED mock_hmac_verify.assert_called_with(ACCESS_KEY_ID, SECRET_ACCESS_KEY) @@ -99,11 +92,9 @@ def test_verify_unverified_secret(self, mock_hmac_verify): def test_verify_unverified_secret_no_match(self, mock_hmac_verify): mock_hmac_verify.side_effect = Exception('oops') - potential_secret = PotentialSecret('test', 'test filename', SECRET_ACCESS_KEY) - assert IBMCosHmacDetector().verify( + assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, '''something={}'''.format(ACCESS_KEY_ID), - potential_secret, ) == VerifiedResult.UNVERIFIED mock_hmac_verify.assert_not_called() From 7ac4d51108785bcda1dcd44fde6237935f18840f Mon Sep 17 00:00:00 2001 From: Xianjun Zhu Date: Fri, 1 Nov 2019 15:34:23 -0400 Subject: [PATCH 7/8] fix: restrict exp --- detect_secrets/plugins/ibm_cos_hmac.py | 2 +- tests/plugins/ibm_cos_hmac_test.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/detect_secrets/plugins/ibm_cos_hmac.py b/detect_secrets/plugins/ibm_cos_hmac.py index 021a9f5da..705d338c7 100644 --- a/detect_secrets/plugins/ibm_cos_hmac.py +++ b/detect_secrets/plugins/ibm_cos_hmac.py @@ -44,7 +44,7 @@ def verify(self, token, content): ) if verify_result is True: return VerifiedResult.VERIFIED_TRUE - except Exception: + except requests.exceptions.RequestException: return VerifiedResult.UNVERIFIED return VerifiedResult.VERIFIED_FALSE diff --git a/tests/plugins/ibm_cos_hmac_test.py b/tests/plugins/ibm_cos_hmac_test.py index 91e71485d..5238f4671 100644 --- a/tests/plugins/ibm_cos_hmac_test.py +++ b/tests/plugins/ibm_cos_hmac_test.py @@ -3,6 +3,7 @@ import textwrap import pytest +import requests import responses from mock import patch @@ -79,7 +80,7 @@ def test_verify_valid_secret(self, mock_hmac_verify): @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') def test_verify_unverified_secret(self, mock_hmac_verify): - mock_hmac_verify.side_effect = Exception('oops') + mock_hmac_verify.side_effect = requests.exceptions.RequestException('oops') assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, @@ -90,7 +91,7 @@ def test_verify_unverified_secret(self, mock_hmac_verify): @patch('detect_secrets.plugins.ibm_cos_hmac.verify_ibm_cos_hmac_credentials') def test_verify_unverified_secret_no_match(self, mock_hmac_verify): - mock_hmac_verify.side_effect = Exception('oops') + mock_hmac_verify.side_effect = requests.exceptions.RequestException('oops') assert IbmCosHmacDetector().verify( SECRET_ACCESS_KEY, From c393f38580819de568077fe0e67d3538088f7320 Mon Sep 17 00:00:00 2001 From: Xianjun Zhu Date: Mon, 11 Nov 2019 19:37:52 -0500 Subject: [PATCH 8/8] address comment --- detect_secrets/plugins/ibm_cos_hmac.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detect_secrets/plugins/ibm_cos_hmac.py b/detect_secrets/plugins/ibm_cos_hmac.py index 705d338c7..b27f3006a 100644 --- a/detect_secrets/plugins/ibm_cos_hmac.py +++ b/detect_secrets/plugins/ibm_cos_hmac.py @@ -42,7 +42,7 @@ def verify(self, token, content): verify_result = verify_ibm_cos_hmac_credentials( key_id, token, ) - if verify_result is True: + if verify_result: return VerifiedResult.VERIFIED_TRUE except requests.exceptions.RequestException: return VerifiedResult.UNVERIFIED