예제 #1
0
def find_account(context):
    opt_hostname_keyword = r'(?:hostname|host|username|id|user|userid|user-id|user-name|' \
        'name|user_id|user_name|uname|account)'
    account = r'(\w[\w\-]*)'
    opt_basic_auth = r'(?:[\w\-:%]*\@)?'

    regexes = (
        RegexBasedDetector.assign_regex_generator(
            prefix_regex=CloudantDetector.cl,
            secret_keyword_regex=opt_hostname_keyword,
            secret_regex=account,
        ),
        re.compile(
            r'{http}{opt_basic_auth}{cl_account}{dot}{cloudant_api_url}'.format(
                http=CloudantDetector.http,
                opt_basic_auth=opt_basic_auth,
                cl_account=account,
                dot=CloudantDetector.dot,
                cloudant_api_url=CloudantDetector.cloudant_api_url,
            ),
            flags=re.IGNORECASE,
        ),
    )

    return [
        match
        for line in context.splitlines()
        for regex in regexes
        for match in regex.findall(line)
    ]
예제 #2
0
class SoftlayerDetector(RegexBasedDetector):
    """Scans for Softlayer credentials."""

    secret_type = 'SoftLayer Credentials'

    # opt means optional
    sl = r'(?:softlayer|sl)(?:_|-|)(?:api|)'
    key_or_pass = r'(?:key|pwd|password|pass|token)'
    secret = r'([a-z0-9]{64})'
    denylist = [
        RegexBasedDetector.assign_regex_generator(
            prefix_regex=sl,
            secret_keyword_regex=key_or_pass,
            secret_regex=secret,
        ),

        re.compile(
            r'(?:http|https)://api.softlayer.com/soap/(?:v3|v3.1)/([a-z0-9]{64})',
            flags=re.IGNORECASE,
        ),
    ]

    def verify(self, token, content):
        usernames = find_username(content)
        if not usernames:
            return VerifiedResult.UNVERIFIED

        for username in usernames:
            return verify_softlayer_key(username, token)

        return VerifiedResult.VERIFIED_FALSE
예제 #3
0
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}(?![a-zA-Z0-9_\-]))'
    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
예제 #4
0
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,
        secret_keyword_regex=key_id_keyword_regex,
        secret_regex=key_id_regex,
    )

    return [
        match for line in content.splitlines() for match in regex.findall(line)
    ]
예제 #5
0
def find_username(content):
    # opt means optional
    username_keyword = (
        r'(?:'
        r'username|id|user|userid|user-id|user-name|'
        r'name|user_id|user_name|uname'
        r')'
    )
    username = r'(\w(?:\w|_|@|\.|-)+)'
    regex = re.compile(
        RegexBasedDetector.assign_regex_generator(
            prefix_regex=SoftlayerDetector.sl,
            secret_keyword_regex=username_keyword,
            secret_regex=username,
        ),
    )

    return [
        match
        for line in content.splitlines()
        for match in regex.findall(line)
    ]
예제 #6
0
class IbmCosHmacDetector(RegexBasedDetector):
    """Scans for IBM Cloud Object Storage HMAC credentials."""
    # 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}(?![a-f0-9]))'
    denylist = (RegexBasedDetector.assign_regex_generator(
        prefix_regex=token_prefix,
        secret_keyword_regex=password_keyword,
        secret_regex=password,
    ), )

    def verify(self, token, content):
        key_id_matches = find_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:
                    return VerifiedResult.VERIFIED_TRUE
        except requests.exceptions.RequestException:
            return VerifiedResult.UNVERIFIED

        return VerifiedResult.VERIFIED_FALSE
예제 #7
0
class CloudantDetector(RegexBasedDetector):
    """Scans for Cloudant credentials."""

    secret_type = 'Cloudant Credentials'

    # opt means optional
    dot = r'\.'
    cl_account = r'[\w\-]+'
    cl = r'(?:cloudant|cl|clou)'
    opt_api = r'(?:api|)'
    cl_key_or_pass = opt_api + r'(?:key|pwd|pw|password|pass|token)'
    cl_pw = r'([0-9a-f]{64})'
    cl_api_key = r'([a-z]{24})'
    colon = r'\:'
    at = r'\@'
    http = r'(?:https?\:\/\/)'
    cloudant_api_url = r'cloudant\.com'
    denylist = [
        RegexBasedDetector.assign_regex_generator(
            prefix_regex=cl,
            secret_keyword_regex=cl_key_or_pass,
            secret_regex=cl_pw,
        ),
        RegexBasedDetector.assign_regex_generator(
            prefix_regex=cl,
            secret_keyword_regex=cl_key_or_pass,
            secret_regex=cl_api_key,
        ),
        re.compile(
            r'{http}{cl_account}{colon}{cl_pw}{at}{cl_account}{dot}{cloudant_api_url}'.format(
                http=http,
                colon=colon,
                cl_account=cl_account,
                cl_pw=cl_pw,
                at=at,
                dot=dot,
                cloudant_api_url=cloudant_api_url,
            ),
            flags=re.IGNORECASE,
        ),
        re.compile(
            r'{http}{cl_account}{colon}{cl_api_key}{at}{cl_account}{dot}{cloudant_api_url}'.format(
                http=http,
                colon=colon,
                cl_account=cl_account,
                cl_api_key=cl_api_key,
                at=at,
                dot=dot,
                cloudant_api_url=cloudant_api_url,
            ),
            flags=re.IGNORECASE,
        ),
    ]

    def verify(self, token, context):

        hosts = find_account(context)
        if not hosts:
            return VerifiedResult.UNVERIFIED

        for host in hosts:
            return verify_cloudant_key(host, token)

        return VerifiedResult.VERIFIED_FALSE