github-guardian 1.0.2__tar.gz → 1.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-guardian
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Deep Forensic Security Audit Engine & Pre-Commit Shield
5
5
  Author: GitHub Guardian Team
6
6
  Requires-Dist: typer>=0.9.0
@@ -1,20 +1,49 @@
1
1
  import os
2
2
  import re
3
+ import math
3
4
  from rich.table import Table
4
5
 
5
- # Re-using the professional-grade patterns from the backend
6
+ # Robust set of enterprise-grade patterns
6
7
  SECRET_PATTERNS = {
7
- "AWS Access Key": r'AKIA[0-9A-Z]{16}',
8
- "GitHub Token": r'ghp_[0-9a-zA-Z]{36}',
8
+ "AWS Access Key ID": r'AKIA[0-9A-Z]{16}',
9
+ "AWS Secret Key": r'(?i)aws_secret_access_key\s*[:=]\s*["\']?([A-Za-z0-9/+=]{40})["\']?',
10
+ "GitHub Token": r'gh[pousr]_[0-9a-zA-Z]{36}|github_pat_[0-9a-zA-Z]{82}',
9
11
  "Slack Webhook": r'https://hooks\.slack\.com/services/T[0-9A-Z]{8}/B[0-9A-Z]{8}/[0-9a-zA-Z]{24}',
10
- "Stripe API Key": r'sk_live_[0-9a-zA-Z]{24}',
11
- "Private Key": r'-----BEGIN (?:RSA|OPENSSH) PRIVATE KEY-----',
12
+ "Slack Token": r'xox[bapr]-[0-9a-zA-Z]{10,48}',
13
+ "Stripe API Key": r'[rs]k_(?:live|test)_[0-9a-zA-Z]{24,32}',
12
14
  "Google API Key": r'AIza[0-9A-Za-z\-_]{35}',
13
- "OpenAI API Key": r'sk\s*-\s*[a-zA-Z0-9\-_]{40,}'
15
+ "OpenAI API Key": r'sk-[a-zA-Z0-9]{20,}|sk\s*-\s*[a-zA-Z0-9\-_]{40,}',
16
+ "Twilio Account SID": r'AC[0-9a-fA-F]{32}',
17
+ "Twilio Auth Token": r'(?i)twilio_auth_token\s*[:=]\s*["\']?([0-9a-fA-F]{32})["\']?',
18
+ "Discord Webhook": r'https://discord(?:app)?\.com/api/webhooks/[0-9]+/[0-9a-zA-Z_-]+',
19
+ "Discord Bot Token": r'[MN][A-Za-z0-9_]{23}\.[A-Za-z0-9_]{6}\.[A-Za-z0-9_]{27}',
20
+ "Telegram Bot Token": r'[0-9]{9,10}:[a-zA-Z0-9_-]{35}',
21
+ "Heroku API Key": r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}',
22
+ "Mailgun API Key": r'key-[0-9a-zA-Z]{32}',
23
+ "SendGrid API Key": r'SG\.[0-9a-zA-Z_-]{22}\.[0-9a-zA-Z_-]{43}',
24
+ "Facebook Access Token": r'EAACEdEose0c[0-9A-Za-z]+',
25
+ "Database URL": r'(?:mongodb(?:\+srv)?|postgres|postgresql|mysql|mssql|redis):\/\/[^:\s]+:[^@\s]+@[^@\s]+',
26
+ "Private Key": r'-----BEGIN (?:RSA|OPENSSH|DSA|EC|PGP)? PRIVATE KEY-----',
27
+ "JWT": r'eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+',
28
+ "NPM Token": r'npm_[0-9a-zA-Z]{36}'
14
29
  }
15
30
 
31
+ GENERIC_ASSIGNMENT_PATTERN = re.compile(
32
+ r"(?i)\b['\"]?([a-z0-9_\-\.]*(?:key|secret|token|password|passwd|pw|auth|cred|pass|db|uri|url)[a-z0-9_\-\.]*)['\"]?\s*[:=]\s*['\"]([a-zA-Z0-9_\-\.\/\+=]{16,})['\"]"
33
+ )
34
+
35
+ def calculate_entropy(s: str) -> float:
36
+ if not s:
37
+ return 0.0
38
+ entropy = 0.0
39
+ for x in range(256):
40
+ p_x = float(s.count(chr(x))) / len(s)
41
+ if p_x > 0:
42
+ entropy += - p_x * math.log(p_x, 2)
43
+ return entropy
44
+
16
45
  SAST_PATTERNS = {
17
- "SQL Injection (Raw Query)": r"\.execute\(\".*%\s*\"",
46
+ "SQL Injection (Raw Query)": r"\.execute\(\s*['\"].*['\"]\s*%\s*",
18
47
  "Insecure Rendering (XSS)": r"dangerouslySetInnerHTML",
19
48
  "Hardcoded Auth/Secret": r"password\s*=\s*['\"][^'\"]+['\"]"
20
49
  }
@@ -37,11 +66,20 @@ def run_local_scan(path: str, console, hook_mode: bool = False) -> bool:
37
66
 
38
67
  for root, _, files in os.walk(path):
39
68
  # Ignore common build/dependency directories
40
- if any(x in root for x in [".git", "node_modules", "venv", "__pycache__"]):
69
+ split_dirs = root.split(os.sep)
70
+ if any(x in split_dirs for x in [".git", "node_modules", "venv", ".venv", "build_env", "dist", "build", "__pycache__"]):
41
71
  continue
42
72
  for file in files:
43
- ext = os.path.splitext(file)[1]
44
- if ext in [".png", ".jpg", ".pdf", ".zip", ".pyc"]:
73
+ ext = os.path.splitext(file)[1].lower()
74
+ if ext in [
75
+ ".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico",
76
+ ".pdf", ".zip", ".gz", ".tar", ".pyc", ".exe",
77
+ ".dll", ".so", ".dylib", ".woff", ".woff2", ".ttf", ".eot",
78
+ ".tldr", ".drawio", ".map", ".mp3", ".mp4", ".mov", ".wav"
79
+ ]:
80
+ continue
81
+
82
+ if file.lower() in ["package-lock.json", "yarn.lock", "pnpm-lock.yaml", "poetry.lock", "cargo.lock", "composer.lock"]:
45
83
  continue
46
84
 
47
85
  # Skip the scanner scripts themselves to prevent false positives!
@@ -55,9 +93,20 @@ def run_local_scan(path: str, console, hook_mode: bool = False) -> bool:
55
93
 
56
94
  for line_idx, line in enumerate(lines, 1):
57
95
  # Check for Secrets
96
+ matched_any = False
58
97
  for name, pat in SECRET_PATTERNS.items():
59
98
  if re.search(pat, line):
60
99
  findings.append((filepath, line_idx, "SECRET LEAK", name))
100
+ matched_any = True
101
+
102
+ # If no specific patterns matched, check for generic high-entropy assignments
103
+ if not matched_any:
104
+ gen_match = GENERIC_ASSIGNMENT_PATTERN.search(line)
105
+ if gen_match:
106
+ val = gen_match.group(2)
107
+ # Only alert if value has high entropy
108
+ if calculate_entropy(val) >= 3.2:
109
+ findings.append((filepath, line_idx, "SECRET LEAK", f"High-Entropy Secret ({gen_match.group(1)})"))
61
110
 
62
111
  # Check for Semantic vulnerabilities
63
112
  for name, pat in SAST_PATTERNS.items():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-guardian
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Deep Forensic Security Audit Engine & Pre-Commit Shield
5
5
  Author: GitHub Guardian Team
6
6
  Requires-Dist: typer>=0.9.0
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="github-guardian",
5
- version="1.0.2",
5
+ version="1.0.4",
6
6
  description="Deep Forensic Security Audit Engine & Pre-Commit Shield",
7
7
  author="GitHub Guardian Team",
8
8
  packages=find_packages(),