Skip to content

Commit

Permalink
↪️ Merge pull request Yelp#259 from killuazhu/kyle-contribute-ibm-iam
Browse files Browse the repository at this point in the history
New plugin for ibm cloud IAM key
  • Loading branch information
KevinHock authored Oct 30, 2019
2 parents c1da1af + 6b19cd9 commit 9939cbb
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ The current heuristic searches we implement out of the box include:

* **SoftlayerDetector**: checks for Softlayer tokens.

* **IbmCloudIamDetector**: checks for IBM Cloud IAM key.


See [detect_secrets/
plugins](https://github.com/Yelp/detect-secrets/tree/master/detect_secrets/plugins)
for more details.
Expand Down
51 changes: 51 additions & 0 deletions detect_secrets/plugins/ibm_cloud_iam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from __future__ import absolute_import

import requests

from .base import RegexBasedDetector
from detect_secrets.core.constants import VerifiedResult


class IbmCloudIamDetector(RegexBasedDetector):
"""Scans for IBM Cloud IAM Key."""

secret_type = 'IBM Cloud IAM Key'

# opt means optional
opt_ibm_cloud_iam = r'(?:ibm(?:_|-|)cloud(?:_|-|)iam|cloud(?:_|-|)iam|' + \
r'ibm(?:_|-|)cloud|ibm(?:_|-|)iam|ibm|iam|cloud|)'
opt_dash_undrscr = r'(?:_|-|)'
opt_api = r'(?:api|)'
key_or_pass = r'(?:key|pwd|password|pass|token)'
secret = r'([a-zA-Z0-9_\-]{44})'
denylist = [
RegexBasedDetector.assign_regex_generator(
prefix_regex=opt_ibm_cloud_iam + opt_dash_undrscr + opt_api,
secret_keyword_regex=key_or_pass,
secret_regex=secret,
),
]

def verify(self, token, **kwargs):
response = verify_cloud_iam_api_key(token)

return VerifiedResult.VERIFIED_TRUE if response.status_code == 200 \
else VerifiedResult.VERIFIED_FALSE


def verify_cloud_iam_api_key(apikey): # pragma: no cover
if type(apikey) == bytes:
apikey = apikey.decode('UTF-8')
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
}
response = requests.post(
'https://iam.cloud.ibm.com/identity/token',
headers=headers,
data={
'grant_type': 'urn:ibm:params:oauth:grant-type:apikey',
'apikey': apikey,
},
)
return response
93 changes: 93 additions & 0 deletions tests/plugins/ibm_cloud_iam_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from __future__ import absolute_import

import pytest
import responses

from detect_secrets.core.constants import VerifiedResult
from detect_secrets.plugins.ibm_cloud_iam import IbmCloudIamDetector


CLOUD_IAM_KEY = 'abcd1234abcd1234abcd1234ABCD1234ABCD1234--__'
CLOUD_IAM_KEY_BYTES = b'abcd1234abcd1234abcd1234ABCD1234ABCD1234--__'


class TestIBMCloudIamDetector(object):

@pytest.mark.parametrize(
'payload, should_flag',
[
('ibm-cloud_api_key: {cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_cloud_iam-key : {cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('IBM-API-KEY : "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('"iam_api_key" : "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('cloud-api-key: "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('"iam-password": "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('CLOUD_IAM_API_KEY:"{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm-cloud-key:{cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_key:"{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
(
'"ibm_cloud_iam_api_key":"{cloud_iam_key}"'.format(
cloud_iam_key=CLOUD_IAM_KEY,
), True,
),
('ibm_cloud_iamapikey= {cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_cloud_api_key= "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('IBMCLOUDIAMAPIKEY={cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('cloud_iam_api_key="{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_api_key := {cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('"ibm-iam_key" := "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
(
'"ibm_cloud_iam_api_key":= "{cloud_iam_key}"'.format(
cloud_iam_key=CLOUD_IAM_KEY,
), True,
),
('ibm-cloud_api_key:={cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('"cloud_iam_api_key":="{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_iam_key:= "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_api_key:="{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm_password = "{cloud_iam_key}"'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('ibm-cloud-pwd = {cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('apikey:{cloud_iam_key}'.format(cloud_iam_key=CLOUD_IAM_KEY), True),
('iam_api_key="%s" % IBM_IAM_API_KEY_ENV', False),
('CLOUD_APIKEY: "insert_key_here"', False),
('cloud-iam-key:=afakekey', False),
('fake-cloud-iam-key= "not_long_enough"', False),
],
)
def test_analyze_string_content(self, payload, should_flag):
logic = IbmCloudIamDetector()

output = logic.analyze_string_content(payload, 1, 'mock_filename')
assert len(output) == (1 if should_flag else 0)

@responses.activate
def test_verify_invalid_secret(self):
responses.add(
responses.POST, 'https://iam.cloud.ibm.com/identity/token', status=400,
)

assert IbmCloudIamDetector().verify(CLOUD_IAM_KEY) == VerifiedResult.VERIFIED_FALSE

@responses.activate
def test_verify_valid_secret(self):
responses.add(
responses.POST, 'https://iam.cloud.ibm.com/identity/token', status=200,
)

IbmCloudIamDetector().verify(CLOUD_IAM_KEY) == VerifiedResult.VERIFIED_TRUE

@responses.activate
def test_verify_invalid_secret_bytes(self):
responses.add(
responses.POST, 'https://iam.cloud.ibm.com/identity/token', status=400,
)

assert IbmCloudIamDetector().verify(CLOUD_IAM_KEY_BYTES) == VerifiedResult.VERIFIED_FALSE

@responses.activate
def test_verify_valid_secret_byes(self):
responses.add(
responses.POST, 'https://iam.cloud.ibm.com/identity/token', status=200,
)

IbmCloudIamDetector().verify(CLOUD_IAM_KEY_BYTES) == VerifiedResult.VERIFIED_TRUE

0 comments on commit 9939cbb

Please sign in to comment.