From 74b58d34005fb7b0667b5624a40493d002dcd908 Mon Sep 17 00:00:00 2001 From: EdOverflow Date: Sat, 9 Nov 2019 17:49:02 +0100 Subject: [PATCH 1/4] Create plugin to detect Twilio API keys. This commit contains a RegexBasedDetector plugin for Twilio API keys. Twilio's API requires an "Account SID" and "auth token" which can be detected by this plugin using two regular expressions. Example account SID: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Regex: AC[a-z0-9]{32} Example auth token: SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Regex: SK[a-z0-9]{32} It might be worth further expanding this plugin to include a verify function that sends a GET request to {}:{}@api.twilio.com/2010-04-01/Accounts.json. --- README.md | 2 +- detect_secrets/plugins/twilio.py | 24 ++++++++++++++++++++++++ tests/plugins/twilio_test.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 detect_secrets/plugins/twilio.py create mode 100644 tests/plugins/twilio_test.py diff --git a/README.md b/README.md index 08470926c..1dc9fd186 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ The current heuristic searches we implement out of the box include: * **KeywordDetector**: checks to see if certain keywords are being used e.g. `password` or `secret` -* **RegexBasedDetector**: checks for any keys matching certain regular expressions (Artifactory, AWS, Slack, Stripe, Mailchimp). +* **RegexBasedDetector**: checks for any keys matching certain regular expressions (Artifactory, AWS, Slack, Stripe, Mailchimp, Twilio). * **JwtTokenDetector**: checks for formally correct JWTs. diff --git a/detect_secrets/plugins/twilio.py b/detect_secrets/plugins/twilio.py new file mode 100644 index 000000000..122139281 --- /dev/null +++ b/detect_secrets/plugins/twilio.py @@ -0,0 +1,24 @@ +""" +This plugin searches for Twilio API keys +""" +from __future__ import absolute_import + +import re + +import requests + +from .base import RegexBasedDetector +from detect_secrets.core.constants import VerifiedResult + + +class TwilioKeyDetector(RegexBasedDetector): + """Scans for Twilio API keys.""" + secret_type = 'Twilio API Key' + + denylist = [ + # Account SID (ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) + re.compile(r'AC[a-z0-9]{32}'), + + # Auth token (SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) + re.compile(r'SK[a-z0-9]{32}'), + ] diff --git a/tests/plugins/twilio_test.py b/tests/plugins/twilio_test.py new file mode 100644 index 000000000..00e3c8dd0 --- /dev/null +++ b/tests/plugins/twilio_test.py @@ -0,0 +1,28 @@ +from __future__ import absolute_import + +import pytest + +from detect_secrets.plugins.twilio import TwilioKeyDetector + + +class TestTwilioKeyDetector(object): + + @pytest.mark.parametrize( + 'payload, should_flag', + [ + ( + 'SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + True + ), + ( + 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + True + ), + ], + ) + + def test_analyze(self, payload, should_flag): + logic = TwilioKeyDetector() + + output = logic.analyze_line(payload, 1, 'mock_filename') + assert len(output) == int(should_flag) From a64996370359bbb2d10f9e4b1ae9d02303538b96 Mon Sep 17 00:00:00 2001 From: EdOverflow Date: Sun, 10 Nov 2019 12:33:54 +0100 Subject: [PATCH 2/4] Run pre-commit against all files. I was importing packages that weren't used in twilio.py. This commit removes those import statements. --- detect_secrets/plugins/twilio.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/detect_secrets/plugins/twilio.py b/detect_secrets/plugins/twilio.py index 122139281..78e149481 100644 --- a/detect_secrets/plugins/twilio.py +++ b/detect_secrets/plugins/twilio.py @@ -5,10 +5,7 @@ import re -import requests - from .base import RegexBasedDetector -from detect_secrets.core.constants import VerifiedResult class TwilioKeyDetector(RegexBasedDetector): From 9f6a38858c074ea634a663a51c47e946684ece19 Mon Sep 17 00:00:00 2001 From: EdOverflow Date: Sun, 10 Nov 2019 13:29:12 +0100 Subject: [PATCH 3/4] Add missing updates to Twilio test file. --- tests/plugins/twilio_test.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/plugins/twilio_test.py b/tests/plugins/twilio_test.py index 00e3c8dd0..8bd8cd201 100644 --- a/tests/plugins/twilio_test.py +++ b/tests/plugins/twilio_test.py @@ -12,17 +12,15 @@ class TestTwilioKeyDetector(object): [ ( 'SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - True + True, ), ( 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - True - ), + True, + ), ], ) - def test_analyze(self, payload, should_flag): logic = TwilioKeyDetector() - output = logic.analyze_line(payload, 1, 'mock_filename') assert len(output) == int(should_flag) From 798ff3fb63a6c16e926fe642a824c71567bf7762 Mon Sep 17 00:00:00 2001 From: EdOverflow Date: Fri, 15 Nov 2019 14:54:28 +0100 Subject: [PATCH 4/4] Just use assert output in test case. As per @domanchi's suggestion in #267. --- tests/plugins/twilio_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/twilio_test.py b/tests/plugins/twilio_test.py index 8bd8cd201..3d2c83fd9 100644 --- a/tests/plugins/twilio_test.py +++ b/tests/plugins/twilio_test.py @@ -23,4 +23,4 @@ class TestTwilioKeyDetector(object): def test_analyze(self, payload, should_flag): logic = TwilioKeyDetector() output = logic.analyze_line(payload, 1, 'mock_filename') - assert len(output) == int(should_flag) + assert output