Last active
August 14, 2023 20:36
-
-
Save RyanJulyan/3bd28fb418920e5c7c2bc91dd68f6577 to your computer and use it in GitHub Desktop.
This Python script scans a code repository for sensitive information like keys and passwords extendable with custom regex patterns. It accepts a root directory and an optional text file, listing files or folders to ignore. Specific lines can be ignored with the comment "ignore: security check."
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import sys | |
import argparse | |
from datetime import datetime | |
from concurrent.futures import as_completed | |
# from concurrent.futures.thread import ThreadPoolExecutor as PoolExecutor | |
from concurrent.futures.process import ProcessPoolExecutor as PoolExecutor | |
from typing import List | |
from rich.console import Console | |
import pyfiglet | |
# Comment pattern to ignore specific lines | |
ignore_comment_pattern = "ignore: security check" | |
def scan_file(file_path, patterns: List[str]): | |
sensitive_information = [] | |
with open(file_path, "r", encoding="utf-8", errors="ignore") as file: | |
content = file.readlines() | |
for line_number, line in enumerate(content, start=1): | |
# Skip lines with the ignore comment pattern | |
if ignore_comment_pattern in line: | |
continue | |
for pattern in patterns: | |
if pattern and isinstance( | |
pattern, str | |
): # Check if pattern is a non-empty string | |
if re.search(pattern, line, re.IGNORECASE): | |
file_link = f"[link=file://{file_path}]{file_path}[/link]" | |
sensitive_information.append( | |
f"Pattern: {pattern} at line {line_number} found in {file_link}" | |
) | |
return sensitive_information | |
def main(): | |
ascii_banner = pyfiglet.figlet_format("Sensitive Information Search") | |
print(ascii_banner) | |
console = Console() | |
# Argument parser to accept the root directory and a file containing the list of files to ignore | |
parser = argparse.ArgumentParser( | |
description="Search for sensitive information in code repository." | |
) | |
parser.add_argument("rootDir", help="Root directory to start the search from") | |
parser.add_argument( | |
"--ignore", | |
help="Path to a text file containing the list of files to ignore", | |
default=None, | |
) | |
parser.add_argument( | |
"--ignore-folders", | |
help="Path to a text file containing the list of folders to ignore", | |
default=None, | |
) | |
parser.add_argument( | |
"--custom-patterns", | |
help="Path to a text file containing custom regex patterns", | |
default=None, | |
) | |
parser.add_argument( | |
"--verbose", help="Print out all the file paths while scanning", default=None | |
) | |
args = parser.parse_args() | |
rootDir = args.rootDir | |
ignore_file_path = args.ignore | |
ignore_folders_path = args.ignore_folders | |
custom_patterns_file_path = args.custom_patterns | |
verbose = args.verbose | |
# Read the ignore file if provided | |
ignore_files = [] | |
if ignore_file_path: | |
with open(ignore_file_path, "r") as ignore_file: | |
ignore_files = [line.strip() for line in ignore_file] | |
# Read the ignore folders if provided | |
ignore_folders = [] | |
if ignore_folders_path: | |
with open(ignore_folders_path, "r") as ignore_folder_file: | |
ignore_folders = [line.strip() for line in ignore_folder_file] | |
# Define regex patterns for keys, passwords, and credentials | |
patterns = [ | |
"(=|:)\s[a-zA-Z0-9]{32}", | |
"(=|:)\s[a-zA-Z0-9]{64}", | |
"(=|:)\s[a-zA-Z0-9]{128}", | |
"(=|:)\s[a-zA-Z0-9]{256}", | |
".*password.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*passwd.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*pwd.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*username.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*user.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*login.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*uname.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{32,}[\"']?", | |
".*api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{32,}[\"']?", | |
".*tkn.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{32,}[\"']?", | |
".*auth.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{32,}[\"']?", | |
"Authorization:\s*Basic\s*[a-zA-Z0-9]{1,}:[a-zA-Z0-9]{1,}", | |
"Authorization:\s*Basic\s*[A-Za-z0-9+/=]+", | |
".*bearer.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*Bearer [A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*", | |
".*oauth.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*OAuth\\s[A-Za-z0-9]*", | |
".*adafruit_io_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*adobe_device_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*adobe_jwt.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*adobe_service_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*adobe_short_lived_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*aiven_auth_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*aiven_service_password.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*alibaba_cloud_access_key_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*alibaba_cloud_access_key_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*amazon_oauth_client_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*amazon_oauth_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*aws_access_key_id.*\s*(=|:)\s*[a-zA-Z0-9]{20,}", | |
".*aws_secret_access_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*aws_session_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*aws_temporary_access_key_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*asana_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*atlassian_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*atlassian_jwt.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*bitbucket_server_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_active_directory_application_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_batch_key_identifiable.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_cache_for_redis_access_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_container_registry_key_identifiable.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_cosmosdb_key_identifiable.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_devops_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_function_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_ml_web_service_classic_identifiable_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_sas_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_search_admin_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_search_query_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_management_certificate.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_sql_connection_string.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_sql_password.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*azure_storage_account_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*beamer_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*cds_canada_notify_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*checkout_production_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*checkout_test_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*chief_tools_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*clojars_deploy_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*codeship_credential.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*contentful_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*CONTRIBUTED_SYSTEMS_CREDENTIAL.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*cratesio_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*databricks_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*DATADOG_API_KEY.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*defined_networking_nebula_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*devcycle_client_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*devcycle_mobile_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*devcycle_server_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*digitalocean_oauth_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*digitalocean_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*digitalocean_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*digitalocean_system_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*discord_api_token_v2.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*discord_bot_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_audit_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_cli_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_personal_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_scim_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_service_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*doppler_service_account_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*dropbox_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*dropbox_short_lived_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*duffel_live_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*duffel_test_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*dynatrace_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*dynatrace_internal_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*easypost_production_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*easypost_test_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ebay_production_client_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ebay_production_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ebay_sandbox_client_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ebay_sandbox_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*fastly_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*figma_pat.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*finicity_app_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*flutterwave_live_api_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*flutterwave_test_api_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*frameio_developer_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*frameio_jwt.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*fullstory_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*github_app_installation_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*github_oauth_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*github_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*github_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*github_ssh_private_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*gitlab_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*gocardless_live_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*gocardless_sandbox_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_cloud_storage_service_account_access_key_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_cloud_storage_access_key_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_cloud_storage_user_access_key_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_cloud_storage_access_key_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_oauth_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_oauth_client_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_oauth_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_oauth_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*google_cloud_private_key_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*grafana_cloud_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*grafana_cloud_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*grafana_project_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*grafana_project_service_account_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*hashicorp_vault_batch_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*hashicorp_vault_root_service_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*hashicorp_vault_service_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*terraform_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*highnote_rk_live_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*highnote_rk_test_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*highnote_sk_live_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*highnote_sk_test_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*hubspot_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*hubspot_api_personal_access_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*intercom_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ionic_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*ionic_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*jd_cloud_access_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*jfrog_platform_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*jfrog_platform_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*jfrog_platform_reference_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*linear_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*linear_oauth_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*lob_live_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*lob_test_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*localstack_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*logicmonitor_bearer_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*logicmonitor_lmv1_access_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*mailchimp_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*MANDRILL_API.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*mailgun_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*mapbox_secret_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*mercury_non_production_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*mercury_production_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*messagebird_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*facebook_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*midtrans_production_server_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*midtrans_sandbox_server_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*new_relic_insights_query_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*new_relic_license_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*new_relic_personal_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*new_relic_rest_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*notion_integration_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*notion_oauth_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*npm_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*nuget_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*octopus_deploy_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*oculus_very_tiny_encrypted_session.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onechronos_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onechronos_eb_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onechronos_eb_encryption_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onechronos_oauth_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onechronos_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onfido_live_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*onfido_sandbox_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*openai_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*palantir_jwt.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*persona_production_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*persona_sandbox_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*pinterest_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*pinterest_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*planetscale_database_password.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*planetscale_oauth_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*planetscale_service_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*plivo_auth_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*plivo_auth_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*postman_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*postman_collection_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*prefect_server_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*prefect_user_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*PREFECT_USER_API_TOKEN.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*proctorio_consumer_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*proctorio_linkage_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*proctorio_registration_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*proctorio_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*pulumi_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*pypi_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*readmeio_api_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*redirect_pizza_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*rootly_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*rubygems_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*samsara_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*samsara_oauth_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*segment_public_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*sendgrid_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*sendinblue_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*sendinblue_smtp_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shippo_live_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shippo_test_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_app_client_credentials.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_app_client_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_app_shared_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_custom_app_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_marketplace_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_merchant_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_partner_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*shopify_private_app_password.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*slack_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*slack_incoming_webhook_url.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*slack_workflow_webhook_url.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*square_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*square_production_application_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*square_sandbox_application_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*sslmate_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*sslmate_cluster_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_live_restricted_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_legacy_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_test_restricted_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_test_secret_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*stripe_webhook_signing_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*supabase_service_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*tableau_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*telegram_bot_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*telnyx_api_v2_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*tencent_cloud_secret_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*tencent_wechat_api_app_id.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*twilio_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*twilio_account_sid.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*twilio_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*typeform_personal_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*unwise_flow_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*wakatime_pp_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*wakatime_oauth_access_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*wakatime_oauth_refresh_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*workato_developer_api_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*workos_production_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*workos_staging_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_iam_access_secret.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_cloud_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_cloud_iam_cookie.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_cloud_iam_token.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_dictionary_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*YANDEX_PASSPORT_OAUTH_TOKEN.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_predictor_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*yandex_translate_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
".*zuplo_consumer_api_key.*\s*(=|:)\s*[\"']?[a-zA-Z0-9]{3,}[\"']?", | |
] | |
# Read the custom patterns file if provided | |
custom_patterns = [] | |
if custom_patterns_file_path: | |
with open(custom_patterns_file_path, "r") as custom_patterns_file: | |
custom_patterns = [ | |
line.strip() for line in custom_patterns_file if line.strip() | |
] | |
# Combine the default patterns with custom patterns | |
patterns.extend(custom_patterns) | |
print("-" * 50) | |
print("Scanning Target: " + rootDir) | |
print("Scanning started at:" + str(datetime.now())) | |
print("-" * 50) | |
# Iterate through the directory | |
with PoolExecutor() as executor: | |
sensitive_information = [] | |
futures = [] | |
for dirName, subdirList, fileList in os.walk(rootDir): | |
# Skip folders in the ignore list | |
if any(ignore_folder in dirName for ignore_folder in ignore_folders): | |
continue | |
for fname in fileList: | |
# Skip files in the ignore list | |
if any(ignore_file == fname for ignore_file in ignore_files): | |
continue | |
file_path = os.path.join(dirName, fname) | |
if verbose: | |
print(f"Review: {file_path}") | |
futures.append(executor.submit(scan_file, file_path, patterns)) | |
for future in as_completed(futures): | |
sensitive_information.extend(future.result()) | |
# Check if any sensitive information is found | |
if sensitive_information: | |
error_message = "\n".join(sensitive_information) | |
print() | |
ascii_sub_banner = pyfiglet.figlet_format("Found") | |
print(ascii_sub_banner) | |
console.print(error_message) | |
sys.exit(1) | |
else: | |
print() | |
ascii_sub_banner = pyfiglet.figlet_format("Safe") | |
print(ascii_sub_banner) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
python check_sensitive_information.py /path/to/your/repository --ignore /path/to/ignore_files.txt --ignore-folders /path/to/ignore_folders.txt custom-patterns /path/to/custom_patterns.txt --verbose true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
token_[a-zA-Z0-9]{15} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.env | |
.gitkeep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.mypy_cache | |
.pytest_cache | |
__pycache__ | |
venv | |
.venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pyfiglet | |
rich |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment