107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Test cases for secret detection script.
|
||
|
|
|
||
|
|
These tests verify that the detect_secrets.py script correctly:
|
||
|
|
1. Detects actual secrets
|
||
|
|
2. Ignores false positives
|
||
|
|
3. Respects exclusion markers
|
||
|
|
"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
import unittest
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
# Add scripts directory to path
|
||
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))
|
||
|
|
|
||
|
|
from detect_secrets import (
|
||
|
|
scan_file,
|
||
|
|
scan_files,
|
||
|
|
should_exclude_file,
|
||
|
|
has_exclusion_marker,
|
||
|
|
is_excluded_match,
|
||
|
|
SECRET_PATTERNS,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class TestSecretDetection(unittest.TestCase):
|
||
|
|
"""Test cases for secret detection."""
|
||
|
|
|
||
|
|
def setUp(self):
|
||
|
|
"""Set up test fixtures."""
|
||
|
|
self.test_dir = tempfile.mkdtemp()
|
||
|
|
|
||
|
|
def tearDown(self):
|
||
|
|
"""Clean up test fixtures."""
|
||
|
|
import shutil
|
||
|
|
shutil.rmtree(self.test_dir, ignore_errors=True)
|
||
|
|
|
||
|
|
def _create_test_file(self, content: str, filename: str = "test.txt") -> str:
|
||
|
|
"""Create a test file with given content."""
|
||
|
|
file_path = os.path.join(self.test_dir, filename)
|
||
|
|
with open(file_path, "w") as f:
|
||
|
|
f.write(content)
|
||
|
|
return file_path
|
||
|
|
|
||
|
|
def test_detect_openai_api_key(self):
|
||
|
|
"""Test detection of OpenAI API keys."""
|
||
|
|
content = "api_key = 'sk-abcdefghijklmnopqrstuvwxyz123456'"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertTrue(any("openai" in f[2].lower() for f in findings))
|
||
|
|
|
||
|
|
def test_detect_private_key(self):
|
||
|
|
"""Test detection of private keys."""
|
||
|
|
content = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy0AHB7MhgwMbRvI0MBZhpF\n-----END RSA PRIVATE KEY-----"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertTrue(any("private" in f[2].lower() for f in findings))
|
||
|
|
|
||
|
|
def test_detect_database_connection_string(self):
|
||
|
|
"""Test detection of database connection strings with credentials."""
|
||
|
|
content = "DATABASE_URL=mongodb://admin:secretpassword@mongodb.example.com:27017/db"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertTrue(any("database" in f[2].lower() for f in findings))
|
||
|
|
|
||
|
|
def test_detect_password_in_config(self):
|
||
|
|
"""Test detection of hardcoded passwords."""
|
||
|
|
content = "password = 'mysecretpassword123'"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertTrue(any("password" in f[2].lower() for f in findings))
|
||
|
|
|
||
|
|
def test_exclude_placeholder_passwords(self):
|
||
|
|
"""Test that placeholder passwords are excluded."""
|
||
|
|
content = "password = 'changeme'"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertEqual(len(findings), 0)
|
||
|
|
|
||
|
|
def test_exclude_localhost_database_url(self):
|
||
|
|
"""Test that localhost database URLs are excluded."""
|
||
|
|
content = "DATABASE_URL=mongodb://admin:secret@localhost:27017/db"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertEqual(len(findings), 0)
|
||
|
|
|
||
|
|
def test_pragma_allowlist_secret(self):
|
||
|
|
"""Test '# pragma: allowlist secret' marker."""
|
||
|
|
content = "api_key = 'sk-abcdefghijklmnopqrstuvwxyz123456' # pragma: allowlist secret"
|
||
|
|
file_path = self._create_test_file(content)
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertEqual(len(findings), 0)
|
||
|
|
|
||
|
|
def test_empty_file(self):
|
||
|
|
"""Test scanning empty file."""
|
||
|
|
file_path = self._create_test_file("")
|
||
|
|
findings = scan_file(file_path)
|
||
|
|
self.assertEqual(len(findings), 0)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main(verbosity=2)
|