diff --git a/detect_secrets/core/usage.py b/detect_secrets/core/usage.py index 979e8a1a2..43b2c7746 100644 --- a/detect_secrets/core/usage.py +++ b/detect_secrets/core/usage.py @@ -251,6 +251,11 @@ class PluginOptions(object): disable_flag_text='--no-aws-key-scan', disable_help_text='Disables scanning for AWS keys.', ), + PluginDescriptor( + classname='SlackDetector', + disable_flag_text='--no-slack-scan', + disable_help_text='Disables scanning for Slack tokens.', + ), ] def __init__(self, parser): diff --git a/detect_secrets/plugins/common/initialize.py b/detect_secrets/plugins/common/initialize.py index d99bf1ed4..2d87b9fd7 100644 --- a/detect_secrets/plugins/common/initialize.py +++ b/detect_secrets/plugins/common/initialize.py @@ -11,6 +11,7 @@ from ..high_entropy_strings import HexHighEntropyString # noqa: F401 from ..keyword import KeywordDetector # noqa: F401 from ..private_key import PrivateKeyDetector # noqa: F401 +from ..slack import SlackDetector # noqa: F401 from detect_secrets.core.log import log diff --git a/detect_secrets/plugins/slack.py b/detect_secrets/plugins/slack.py new file mode 100644 index 000000000..b3ec7a1c9 --- /dev/null +++ b/detect_secrets/plugins/slack.py @@ -0,0 +1,15 @@ +""" +This plugin searches for Slack tokens +""" +from __future__ import absolute_import + +import re + +from .base import RegexBasedDetector + + +class SlackDetector(RegexBasedDetector): + secret_type = 'Slack Token' + blacklist = ( + re.compile(r'xox(?:a|b|p|o|s|r)-(?:\d+-)+[a-z0-9]+', flags=re.IGNORECASE), + ) diff --git a/tests/core/usage_test.py b/tests/core/usage_test.py index 7e549e868..5e9108a9c 100644 --- a/tests/core/usage_test.py +++ b/tests/core/usage_test.py @@ -37,6 +37,7 @@ def test_consolidates_output_basic(self): 'KeywordDetector': {}, 'PrivateKeyDetector': {}, 'AWSKeyDetector': {}, + 'SlackDetector': {}, } assert not hasattr(args, 'no_private_key_scan') diff --git a/tests/main_test.py b/tests/main_test.py index abce1e165..fae0bd261 100644 --- a/tests/main_test.py +++ b/tests/main_test.py @@ -67,6 +67,7 @@ def test_scan_string_basic(self, mock_baseline_initialize): HexHighEntropyString : True (3.459) KeywordDetector : False PrivateKeyDetector : False + SlackDetector : False """)[1:] mock_baseline_initialize.assert_not_called() @@ -85,6 +86,7 @@ def test_scan_string_cli_overrides_stdin(self): HexHighEntropyString : False (2.121) KeywordDetector : False PrivateKeyDetector : False + SlackDetector : False """)[1:] def test_scan_with_all_files_flag(self, mock_baseline_initialize): diff --git a/tests/plugins/slack_test.py b/tests/plugins/slack_test.py new file mode 100644 index 000000000..ffeb89b33 --- /dev/null +++ b/tests/plugins/slack_test.py @@ -0,0 +1,45 @@ +from __future__ import absolute_import +from __future__ import unicode_literals + +import pytest + +from detect_secrets.plugins.slack import SlackDetector +from testing.mocks import mock_file_object + + +class TestSlackDetector(object): + + @pytest.mark.parametrize( + 'file_content', + [ + ( + 'xoxp-523423-234243-234233-e039d02840a0b9379c' + ), + ( + 'xoxo-523423-234243-234233-e039d02840a0b9379c' + ), + ( + 'xoxs-523423-234243-234233-e039d02840a0b9379c' + ), + ( + 'xoxa-511111111-31111111111-3111111111111-e039d02840a0b9379c' + ), + ( + 'xoxa-2-511111111-31111111111-3111111111111-e039d02840a0b9379c' + ), + ( + 'xoxr-523423-234243-234233-e039d02840a0b9379c' + ), + ( + 'xoxb-34532454-e039d02840a0b9379c' + ), + ], + ) + def test_analyze(self, file_content): + logic = SlackDetector() + + f = mock_file_object(file_content) + output = logic.analyze(f, 'mock_filename') + assert len(output) == 1 + for potential_secret in output: + assert 'mock_filename' == potential_secret.filename diff --git a/tests/pre_commit_hook_test.py b/tests/pre_commit_hook_test.py index ef795172e..71fcd3b71 100644 --- a/tests/pre_commit_hook_test.py +++ b/tests/pre_commit_hook_test.py @@ -151,6 +151,9 @@ def test_that_baseline_gets_updated( { 'name': 'PrivateKeyDetector', }, + { + 'name': 'SlackDetector', + }, ] def test_writes_new_baseline_if_modified(self):