Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AzureStorageKeyDetector scan multi lines and skip public keys #178

Merged
merged 7 commits into from
Jan 23, 2024
52 changes: 51 additions & 1 deletion detect_secrets/plugins/azure_storage_key.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
"""
This plugin searches for Azure Storage Account access keys.
"""
from __future__ import annotations

import re
from typing import Any
from typing import List
from typing import Optional
from typing import Set

from detect_secrets.core.potential_secret import PotentialSecret
from detect_secrets.plugins.base import RegexBasedDetector

from detect_secrets.util.code_snippet import CodeSnippet

class AzureStorageKeyDetector(RegexBasedDetector):
"""Scans for Azure Storage Account access keys."""
Expand All @@ -16,3 +23,46 @@ class AzureStorageKeyDetector(RegexBasedDetector):
r'(?:["\']?[A-Za-z0-9+\/]{86,1000}==["\']?)$',
),
]

skip_keys = [
r'PublicKey[s]?:[a-z-\s\n>]*{secret}',
]

def analyze_line(
self,
filename: str,
line: str,
line_number: int = 0,
context: Optional[CodeSnippet] = None,
raw_context: Optional[CodeSnippet] = None,
**kwargs: Any,
) -> Set[PotentialSecret]:
output: Set[PotentialSecret] = set()
results = super().analyze_line(
filename=filename, line=line, line_number=line_number,
context=context, raw_context=raw_context, **kwargs,
)
output.update(self.filter_skip_keys(results, context, line))

return output

def filter_skip_keys(
self,
results: Set[PotentialSecret],
context: Optional[CodeSnippet],
line: str,
) -> List[PotentialSecret]:
context_text = ''.join(context.lines) if context else line
return [result for result in results if not self.skip_keys_exists(result, context_text)]

def skip_keys_exists(self, result: PotentialSecret, string: str) -> bool:
if result.secret_value:
for secret_regex in self.skip_keys:
regex = re.compile(
secret_regex.format(
secret=re.escape(result.secret_value),
), re.DOTALL,
)
if regex.search(string) is not None:
return True
return False
44 changes: 44 additions & 0 deletions tests/plugins/azure_storage_key_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,50 @@ class TestAzureStorageKeyDetector:
'cret',
False,
),

# Test skip only public keys
(
'PublicKey: lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
False,
),
(
'PublicKey: ssh-rsa lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
False,
),
(
'SshPublicKey: ssh-rsa lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
False,
),
(
'PublicKeys: lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
False,
),
(
'SshPublicKeys: lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
False,
),
(
'PrivateKeys: lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==',
True,
),

# Test multilines
(
"""PrivateKeys:
- lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==""",
True,
),
(
"""SshPublicKeys:
- lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==""",
False,
),
(
"""SshPublicKeys:
- >-
lJzRc1YdHaAA2KCNJJ1tkYwF/+mKK6Ygw0NGe170Xu592euJv2wYUtBlV8z+qnlcNQSnIYVTkLWntUO1F8j8rQ==""",
False,
),
],
)
def test_analyze(self, payload, should_flag):
Expand Down