git-cli-scanner 1.4.0 โ 1.5.1
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.
- package/dist/cli.js +274 -2
- package/package.json +1 -1
- package/readme.md +80 -45
package/dist/cli.js
CHANGED
|
@@ -229,6 +229,20 @@ var init_cloudProviders = __esm({
|
|
|
229
229
|
pattern: /AIza[0-9A-Za-z\-_]{35}/,
|
|
230
230
|
risk: "Attackers can bypass quotas to abuse GCP services like Maps API or Vertex AI, causing high billing charges.",
|
|
231
231
|
solution: "Restrict the key in Google Cloud Console (APIs & Services > Credentials) to specific IP addresses/apps, or revoke it and use GCP Service Accounts."
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
id: "firebase-secret",
|
|
235
|
+
description: "Firebase API Key or Secret",
|
|
236
|
+
pattern: /firebase[_-]?(?:api[_-]?key|secret)[\s:=]+["']?[a-zA-Z0-9\-_]{30,}["']?/i,
|
|
237
|
+
risk: "Attackers can bypass security rules, read/write to your Firebase database, or exhaust quotas.",
|
|
238
|
+
solution: "Revoke the key in the Firebase console and restrict new keys to specific domains or IP addresses."
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: "firebase-service-account",
|
|
242
|
+
description: "Firebase Service Account JSON (Heuristic)",
|
|
243
|
+
pattern: /"type"\s*:\s*"service_account"|-----BEGIN PRIVATE KEY-----/i,
|
|
244
|
+
risk: "Service accounts grant full administrative access to your Firebase project, including databases, auth, and storage.",
|
|
245
|
+
solution: "Delete the service account key in Google Cloud IAM and never commit service account JSON files. Use environment variables."
|
|
232
246
|
}
|
|
233
247
|
];
|
|
234
248
|
cloudProviderScanner = {
|
|
@@ -397,7 +411,7 @@ var init_envFiles = __esm({
|
|
|
397
411
|
scan(diff) {
|
|
398
412
|
const issues = [];
|
|
399
413
|
const filename = diff.file.split("/").pop() || "";
|
|
400
|
-
const bannedExtensions = [".pem", ".key", ".sqlite", ".db", ".log", ".p12", ".pfx"];
|
|
414
|
+
const bannedExtensions = [".pem", ".key", ".sqlite", ".db", ".log", ".p12", ".pfx", ".crt", ".cer", ".keystore"];
|
|
401
415
|
const isEnvFile = /(^|\/)\.env(\..+)?$/.test(diff.file);
|
|
402
416
|
const isNodeModules = diff.file.startsWith("node_modules/");
|
|
403
417
|
if (isEnvFile || isNodeModules || bannedExtensions.some((ext) => diff.file.endsWith(ext))) {
|
|
@@ -458,6 +472,20 @@ var init_infrastructure = __esm({
|
|
|
458
472
|
pattern: /(?:postgres|mysql|mongodb(?:\+srv)?|redis):\/\/[^:\/\s]+:[^@\/\s]+@[^:\/\s]+(?::\d+)?\//,
|
|
459
473
|
risk: "An attacker can directly connect to your database instance, allowing them to steal, modify, or delete all of your user data.",
|
|
460
474
|
solution: "Remove the hardcoded database URL and read it from an environment variable (e.g., process.env.DATABASE_URL) at runtime."
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
id: "smtp-credentials",
|
|
478
|
+
description: "SMTP Email Credentials",
|
|
479
|
+
pattern: /(?:smtp|mail|sendgrid|mailgun)[\w\-]*(?:password|secret|key)[\s:=]+["']?[^"'\s]+["']?/i,
|
|
480
|
+
risk: "Attackers can use your SMTP server to send spam or phishing emails, ruining your domain reputation and incurring massive costs.",
|
|
481
|
+
solution: "Change the SMTP password via your email provider and inject it securely using a secrets manager."
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
id: "terraform-helm-secret",
|
|
485
|
+
description: "Terraform / Helm Variable Secret",
|
|
486
|
+
pattern: /(?:tf_var|helm_var)_[a-zA-Z0-9_]+[\s:=]+["']?[^"'\s]+["']?/i,
|
|
487
|
+
risk: "Hardcoded infrastructure secrets can grant access to the underlying platform resources and services.",
|
|
488
|
+
solution: "Use a proper secrets management backend for Terraform (e.g. Vault) or pass secrets via CI/CD runners."
|
|
461
489
|
}
|
|
462
490
|
];
|
|
463
491
|
infrastructureScanner = {
|
|
@@ -491,6 +519,242 @@ var init_infrastructure = __esm({
|
|
|
491
519
|
}
|
|
492
520
|
});
|
|
493
521
|
|
|
522
|
+
// src/scans/authentication.ts
|
|
523
|
+
var rules6, authenticationScanner;
|
|
524
|
+
var init_authentication = __esm({
|
|
525
|
+
"src/scans/authentication.ts"() {
|
|
526
|
+
"use strict";
|
|
527
|
+
rules6 = [
|
|
528
|
+
{
|
|
529
|
+
id: "jwt-secret",
|
|
530
|
+
description: "JWT Secret Key",
|
|
531
|
+
pattern: /(?:jwt[_-]?(?:secret|key)|secret[_-]?key)[\s:=]+["']?[a-zA-Z0-9\-_!@#$%^&*()=+]{16,}["']?/i,
|
|
532
|
+
risk: "An attacker can forge JWT tokens to impersonate any user, including admins, bypassing all authentication.",
|
|
533
|
+
solution: "Rotate the secret, ensure all existing JWT sessions are invalidated, and inject it via environment variables."
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
id: "oauth-client-secret",
|
|
537
|
+
description: "OAuth Client Secret",
|
|
538
|
+
pattern: /(?:oauth|client)[_-]?(?:secret|key)[\s:=]+["']?[a-zA-Z0-9\-_]{16,}["']?/i,
|
|
539
|
+
risk: "Attackers can hijack the OAuth flow, authenticate on behalf of your users, or exhaust API quotas.",
|
|
540
|
+
solution: "Revoke the OAuth client secret in the identity provider console and generate a new one."
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
id: "session-secret",
|
|
544
|
+
description: "Session Cookie Secret",
|
|
545
|
+
pattern: /(?:session)[_-]?(?:secret|key)[\s:=]+["']?[a-zA-Z0-9\-_!@#$%^&*()=+]{16,}["']?/i,
|
|
546
|
+
risk: "Attackers can forge signed session cookies, allowing them to hijack active user sessions.",
|
|
547
|
+
solution: "Change the session secret to immediately invalidate all current user sessions."
|
|
548
|
+
}
|
|
549
|
+
];
|
|
550
|
+
authenticationScanner = {
|
|
551
|
+
id: "authentication",
|
|
552
|
+
scan(diff) {
|
|
553
|
+
const issues = [];
|
|
554
|
+
const lines = diff.content.split("\n");
|
|
555
|
+
let lineNumber = 1;
|
|
556
|
+
for (const line of lines) {
|
|
557
|
+
if (line.startsWith("+")) {
|
|
558
|
+
const cleanLine = line.substring(1);
|
|
559
|
+
for (const rule of rules6) {
|
|
560
|
+
if (rule.pattern.test(cleanLine)) {
|
|
561
|
+
issues.push({
|
|
562
|
+
type: rule.id,
|
|
563
|
+
file: diff.file,
|
|
564
|
+
line: lineNumber,
|
|
565
|
+
match: cleanLine.trim().substring(0, 50) + "...",
|
|
566
|
+
severity: "high",
|
|
567
|
+
solution: rule.solution,
|
|
568
|
+
risk: rule.risk
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
lineNumber++;
|
|
574
|
+
}
|
|
575
|
+
return issues;
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
// src/scans/packageRegistries.ts
|
|
582
|
+
var rules7, packageRegistryScanner;
|
|
583
|
+
var init_packageRegistries = __esm({
|
|
584
|
+
"src/scans/packageRegistries.ts"() {
|
|
585
|
+
"use strict";
|
|
586
|
+
rules7 = [
|
|
587
|
+
{
|
|
588
|
+
id: "npm-token",
|
|
589
|
+
description: "NPM Access Token",
|
|
590
|
+
pattern: /(?:npm|NPM)[_-]?(?:token|TOKEN)[\s:=]+["']?(?:npm_[a-zA-Z0-9]{36})["']?/i,
|
|
591
|
+
risk: "Attackers can publish malicious versions of your packages (Supply Chain Attack) to compromise all users downloading your code.",
|
|
592
|
+
solution: "Revoke the token immediately on npmjs.com and check your package versions for unauthorized releases."
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
id: "pypi-token",
|
|
596
|
+
description: "PyPI Access Token",
|
|
597
|
+
pattern: /pypi-[a-zA-Z0-9_-]{50,}/,
|
|
598
|
+
risk: "Attackers can upload malicious packages to PyPI under your name, distributing malware to your downstream users.",
|
|
599
|
+
solution: "Revoke the token in your PyPI account settings immediately and inspect recent package uploads."
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
id: "maven-gradle-password",
|
|
603
|
+
description: "Maven/Gradle Repository Password",
|
|
604
|
+
pattern: /(?:maven|gradle|nexus|artifactory)[\w\-]*password[\s:=]+["']?[a-zA-Z0-9\-_!@#$%^&*()=+]{8,}["']?/i,
|
|
605
|
+
risk: "Attackers can access your private artifact repository, steal proprietary code, or inject backdoors into your Java packages.",
|
|
606
|
+
solution: "Change your repository password and remove it from the hardcoded configuration file (e.g. settings.xml)."
|
|
607
|
+
}
|
|
608
|
+
];
|
|
609
|
+
packageRegistryScanner = {
|
|
610
|
+
id: "package-registries",
|
|
611
|
+
scan(diff) {
|
|
612
|
+
const issues = [];
|
|
613
|
+
const lines = diff.content.split("\n");
|
|
614
|
+
let lineNumber = 1;
|
|
615
|
+
for (const line of lines) {
|
|
616
|
+
if (line.startsWith("+")) {
|
|
617
|
+
const cleanLine = line.substring(1);
|
|
618
|
+
for (const rule of rules7) {
|
|
619
|
+
if (rule.pattern.test(cleanLine)) {
|
|
620
|
+
issues.push({
|
|
621
|
+
type: rule.id,
|
|
622
|
+
file: diff.file,
|
|
623
|
+
line: lineNumber,
|
|
624
|
+
match: cleanLine.trim().substring(0, 50) + "...",
|
|
625
|
+
severity: "high",
|
|
626
|
+
solution: rule.solution,
|
|
627
|
+
risk: rule.risk
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
lineNumber++;
|
|
633
|
+
}
|
|
634
|
+
return issues;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
// src/scans/cicd.ts
|
|
641
|
+
var rules8, cicdScanner;
|
|
642
|
+
var init_cicd = __esm({
|
|
643
|
+
"src/scans/cicd.ts"() {
|
|
644
|
+
"use strict";
|
|
645
|
+
rules8 = [
|
|
646
|
+
{
|
|
647
|
+
id: "gitlab-ci-token",
|
|
648
|
+
description: "GitLab Personal Access Token",
|
|
649
|
+
pattern: /glpat-[a-zA-Z0-9\-]{20,}/,
|
|
650
|
+
risk: "Attackers can access your GitLab repositories, modify CI/CD pipelines, and steal sensitive code or deployment secrets.",
|
|
651
|
+
solution: "Revoke the token in your GitLab account (User Settings > Access Tokens) and use environment variables for CI authentication."
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
id: "github-actions-token",
|
|
655
|
+
description: "GitHub Actions Token / Fine-grained PAT",
|
|
656
|
+
pattern: /gh[p|a|s|r]_[a-zA-Z0-9]{36}/,
|
|
657
|
+
risk: "Compromised GitHub tokens can allow attackers to push code, trigger malicious Actions workflows, or steal repository secrets.",
|
|
658
|
+
solution: "Revoke the token immediately in GitHub (Settings > Developer Settings) and switch to short-lived GitHub App tokens if possible."
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
id: "jenkins-token",
|
|
662
|
+
description: "Jenkins Token or API Secret",
|
|
663
|
+
pattern: /(?:jenkins)[\w\-]*(?:token|secret|password)[\s:=]+["']?[a-zA-Z0-9]{20,}["']?/i,
|
|
664
|
+
risk: "Attackers can trigger or modify your Jenkins build pipelines, leading to malicious deployments or lateral movement.",
|
|
665
|
+
solution: "Revoke the API token in the Jenkins User Configuration page and inject secrets using the Jenkins Credentials Manager."
|
|
666
|
+
}
|
|
667
|
+
];
|
|
668
|
+
cicdScanner = {
|
|
669
|
+
id: "cicd-secrets",
|
|
670
|
+
scan(diff) {
|
|
671
|
+
const issues = [];
|
|
672
|
+
const lines = diff.content.split("\n");
|
|
673
|
+
let lineNumber = 1;
|
|
674
|
+
for (const line of lines) {
|
|
675
|
+
if (line.startsWith("+")) {
|
|
676
|
+
const cleanLine = line.substring(1);
|
|
677
|
+
for (const rule of rules8) {
|
|
678
|
+
if (rule.pattern.test(cleanLine)) {
|
|
679
|
+
issues.push({
|
|
680
|
+
type: rule.id,
|
|
681
|
+
file: diff.file,
|
|
682
|
+
line: lineNumber,
|
|
683
|
+
match: cleanLine.trim().substring(0, 50) + "...",
|
|
684
|
+
severity: "critical",
|
|
685
|
+
solution: rule.solution,
|
|
686
|
+
risk: rule.risk
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
lineNumber++;
|
|
692
|
+
}
|
|
693
|
+
return issues;
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// src/scans/webhooks.ts
|
|
700
|
+
var rules9, webhooksScanner;
|
|
701
|
+
var init_webhooks = __esm({
|
|
702
|
+
"src/scans/webhooks.ts"() {
|
|
703
|
+
"use strict";
|
|
704
|
+
rules9 = [
|
|
705
|
+
{
|
|
706
|
+
id: "stripe-secret",
|
|
707
|
+
description: "Stripe Secret Key / Webhook Secret",
|
|
708
|
+
pattern: /(?:sk_live|rk_live|whsec)_[a-zA-Z0-9]{24,}/,
|
|
709
|
+
risk: "Attackers can process fraudulent transactions, issue refunds, or steal customer financial data from your Stripe account.",
|
|
710
|
+
solution: "Roll the secret key immediately in the Stripe Dashboard (Developers > API keys) and monitor recent charges."
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
id: "paypal-secret",
|
|
714
|
+
description: "PayPal Client Secret",
|
|
715
|
+
pattern: /paypal[_-]?(?:client[_-]?secret|secret)[\s:=]+["']?[a-zA-Z0-9\-_]{30,}["']?/i,
|
|
716
|
+
risk: "Attackers can process fraudulent payments, manipulate subscriptions, or steal transaction history.",
|
|
717
|
+
solution: "Revoke the secret in the PayPal Developer Dashboard and generate a new one."
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
id: "generic-webhook",
|
|
721
|
+
description: "Generic Webhook URL (Slack, Discord, etc)",
|
|
722
|
+
pattern: /(?:https?:\/\/)?(?:hooks\.slack\.com|discord\.com\/api\/webhooks|maker\.ifttt\.com)[^\s'"]+/i,
|
|
723
|
+
risk: "Attackers can spam your internal channels, launch phishing attacks on your team, or exhaust rate limits.",
|
|
724
|
+
solution: "Delete the webhook in the respective service platform and re-generate a new URL. Do not commit webhook URLs directly."
|
|
725
|
+
}
|
|
726
|
+
];
|
|
727
|
+
webhooksScanner = {
|
|
728
|
+
id: "webhooks",
|
|
729
|
+
scan(diff) {
|
|
730
|
+
const issues = [];
|
|
731
|
+
const lines = diff.content.split("\n");
|
|
732
|
+
let lineNumber = 1;
|
|
733
|
+
for (const line of lines) {
|
|
734
|
+
if (line.startsWith("+")) {
|
|
735
|
+
const cleanLine = line.substring(1);
|
|
736
|
+
for (const rule of rules9) {
|
|
737
|
+
if (rule.pattern.test(cleanLine)) {
|
|
738
|
+
issues.push({
|
|
739
|
+
type: rule.id,
|
|
740
|
+
file: diff.file,
|
|
741
|
+
line: lineNumber,
|
|
742
|
+
match: cleanLine.trim().substring(0, 50) + "...",
|
|
743
|
+
severity: "high",
|
|
744
|
+
solution: rule.solution,
|
|
745
|
+
risk: rule.risk
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
lineNumber++;
|
|
751
|
+
}
|
|
752
|
+
return issues;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
|
|
494
758
|
// src/scans/index.ts
|
|
495
759
|
var allScanners;
|
|
496
760
|
var init_scans = __esm({
|
|
@@ -502,13 +766,21 @@ var init_scans = __esm({
|
|
|
502
766
|
init_privateKeys();
|
|
503
767
|
init_envFiles();
|
|
504
768
|
init_infrastructure();
|
|
769
|
+
init_authentication();
|
|
770
|
+
init_packageRegistries();
|
|
771
|
+
init_cicd();
|
|
772
|
+
init_webhooks();
|
|
505
773
|
allScanners = [
|
|
506
774
|
apiKeyScanner,
|
|
507
775
|
cloudProviderScanner,
|
|
508
776
|
collaborationScanner,
|
|
509
777
|
privateKeyScanner,
|
|
510
778
|
envFileScanner,
|
|
511
|
-
infrastructureScanner
|
|
779
|
+
infrastructureScanner,
|
|
780
|
+
authenticationScanner,
|
|
781
|
+
packageRegistryScanner,
|
|
782
|
+
cicdScanner,
|
|
783
|
+
webhooksScanner
|
|
512
784
|
];
|
|
513
785
|
}
|
|
514
786
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-cli-scanner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "A powerful interactive CLI tool that scans your codebase for hardcoded secrets, API keys, passwords, and private keys before they reach your Git history.",
|
|
5
5
|
"main": "dist/cli.js",
|
|
6
6
|
"scripts": {
|
package/readme.md
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
# Git CLI Scanner
|
|
2
2
|
|
|
3
|
-
A powerful CLI tool that scans your codebase for hardcoded secrets, API keys, passwords, private keys, database credentials, and
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## What Does It Scan For?
|
|
8
|
-
|
|
9
|
-
Git CLI Scanner uses regex heuristics and pattern matching to detect:
|
|
10
|
-
|
|
11
|
-
- **Cloud Provider Keys**: AWS Access/Secret Keys, Google Cloud API Keys.
|
|
12
|
-
- **Infrastructure & Databases**: Database Connection Strings (MongoDB, PostgreSQL, MySQL, Redis), Docker Hub Personal Access Tokens.
|
|
13
|
-
- **Collaboration Tools**: Slack Tokens, Slack Webhooks, GitHub PATs, OAuth Tokens, Discord Webhooks.
|
|
14
|
-
- **Private Keys**: RSA, DSA, EC, OpenSSH, PGP Private Keys.
|
|
15
|
-
- **Banned Files**: Accidental commits of `.env`, `.pem`, `.sqlite`, `.log` files (unless they are explicitly added to `.gitignore`).
|
|
16
|
-
|
|
17
|
-
It features an intelligent **Ignore System** (Dummy Detection) that automatically downgrades the severity of fake, dummy, or test secrets commonly used in unit tests (e.g., `1234567890abcdef`, `dummy_token`).
|
|
3
|
+
A powerful CLI tool that scans your codebase for hardcoded secrets, API keys, passwords, private keys, database credentials, Docker tokens, CI/CD secrets, and infrastructure configs before they reach your Git history.
|
|
18
4
|
|
|
19
5
|
---
|
|
20
6
|
|
|
@@ -30,26 +16,18 @@ npx git-cli-scanner <command>
|
|
|
30
16
|
|
|
31
17
|
---
|
|
32
18
|
|
|
33
|
-
## ๐
|
|
34
|
-
|
|
35
|
-
### Commands Overview
|
|
19
|
+
## ๐ Commands
|
|
36
20
|
|
|
37
21
|
| Command | Description | Arguments & Flags | Example Usage |
|
|
38
22
|
|---------|-------------|-------------------|---------------|
|
|
39
23
|
| `init` | Installs the pre-commit hook to automatically scan files on `git commit`. | None | `npx git-cli-scanner init` |
|
|
40
24
|
| `disable` | Removes the pre-commit hook to stop automatic scanning. | None | `npx git-cli-scanner disable` |
|
|
41
|
-
| `scan` | Manually scans the currently staged files (files added via `git add`). | `--show-sol`
|
|
42
|
-
| `scan-all` | Recursively scans an entire directory for secrets. | `<dir>`
|
|
43
|
-
| `scan-history
|
|
44
|
-
| `explore` | Launches an interactive Terminal User Interface (TUI) to
|
|
45
|
-
|
|
46
|
-
### 6. Interactive File Explorer (TUI)
|
|
47
|
-
|
|
48
|
-
Launch an interactive Terminal User Interface (TUI) to navigate your project directory and manually select files to scan.
|
|
25
|
+
| `scan` | Manually scans the currently staged files (files added via `git add`). | `--show-sol` โ Show suggested fixes for each finding | `npx git-cli-scanner scan`<br>`npx git-cli-scanner scan --show-sol` |
|
|
26
|
+
| `scan-all` | Recursively scans an entire directory for secrets. | `<dir>` โ The directory to scan<br>`--show-sol` โ Show suggested fixes | `npx git-cli-scanner scan-all .`<br>`npx git-cli-scanner scan-all ./src --show-sol` |
|
|
27
|
+
| `scan-history` | Scans Git commit history for leaked secrets (Time Travel). Defaults to the last commit. | `--id <hash>` โ Scan a specific commit<br>`--since="<time>"` โ Scan commits from a time range<br>`--all` โ Scan entire history across all branches<br>`--show-sol` โ Show fixes | `npx git-cli-scanner scan-history`<br>`npx git-cli-scanner scan-history --id 3a4b5c6`<br>`npx git-cli-scanner scan-history --since="30 days ago"`<br>`npx git-cli-scanner scan-history --all --show-sol` |
|
|
28
|
+
| `explore` | Launches an interactive Terminal User Interface (TUI) to browse and scan files. | None | `npx git-cli-scanner explore` |
|
|
49
29
|
|
|
50
|
-
|
|
51
|
-
git-cli-scanner explore
|
|
52
|
-
```
|
|
30
|
+
### Interactive Explorer Keys
|
|
53
31
|
|
|
54
32
|
| Key | Action |
|
|
55
33
|
|-----|--------|
|
|
@@ -60,41 +38,98 @@ git-cli-scanner explore
|
|
|
60
38
|
|
|
61
39
|
---
|
|
62
40
|
|
|
63
|
-
##
|
|
41
|
+
## ๐ What Does It Scan For?
|
|
42
|
+
|
|
43
|
+
### Scanners & Detection Rules
|
|
44
|
+
|
|
45
|
+
| Category | Rule ID | What It Detects | Severity |
|
|
46
|
+
|----------|---------|-----------------|----------|
|
|
47
|
+
| โ๏ธ Cloud Providers | `aws-access-key` | AWS Access Key IDs (`AKIA...`) | High |
|
|
48
|
+
| โ๏ธ Cloud Providers | `aws-secret-key` | AWS Secret Access Keys (heuristics) | High |
|
|
49
|
+
| โ๏ธ Cloud Providers | `gcp-api-key` | Google Cloud API Keys (`AIza...`) | High |
|
|
50
|
+
| ๐ฅ Firebase | `firebase-secret` | Firebase API Keys / Secrets | High |
|
|
51
|
+
| ๐ฅ Firebase | `firebase-service-account` | Firebase Service Account JSON (`"type": "service_account"`) | Critical |
|
|
52
|
+
| ๐ชช Authentication | `jwt-secret` | JWT Secret Keys (quoted or unquoted) | High |
|
|
53
|
+
| ๐ชช Authentication | `oauth-client-secret` | OAuth Client Secrets | High |
|
|
54
|
+
| ๐ชช Authentication | `session-secret` | Session Cookie Secrets | High |
|
|
55
|
+
| ๐ API Keys & Tokens | `generic-api-key` | Generic `api_key`, `api-key`, `API_KEY` patterns | High |
|
|
56
|
+
| ๐ API Keys & Tokens | `stripe-key` | Stripe API Keys (`sk_live_...`, `rk_live_...`) | High |
|
|
57
|
+
| ๐ API Keys & Tokens | `github-pat` | GitHub Personal Access Tokens | High |
|
|
58
|
+
| ๐ API Keys & Tokens | `slack-token` | Slack Bot/User Tokens (`xoxb-...`, `xoxp-...`) | High |
|
|
59
|
+
| ๐ API Keys & Tokens | `slack-webhook` | Slack Incoming Webhook URLs | High |
|
|
60
|
+
| ๐ API Keys & Tokens | `discord-webhook` | Discord Webhook URLs | High |
|
|
61
|
+
| ๐ฆ Package Registries | `npm-token` | NPM Access Tokens (`npm_...`) | High |
|
|
62
|
+
| ๐ฆ Package Registries | `pypi-token` | PyPI Access Tokens (`pypi-...`) | High |
|
|
63
|
+
| ๐ฆ Package Registries | `maven-gradle-password` | Maven/Gradle/Nexus/Artifactory Repository Passwords | High |
|
|
64
|
+
| ๐งฐ CI/CD | `gitlab-ci-token` | GitLab Personal Access Tokens (`glpat-...`) | Critical |
|
|
65
|
+
| ๐งฐ CI/CD | `github-actions-token` | GitHub Actions Runner Tokens (`ghp_...`, `ghs_...`) | Critical |
|
|
66
|
+
| ๐งฐ CI/CD | `jenkins-token` | Jenkins API Tokens / Secrets | High |
|
|
67
|
+
| ๐ Infrastructure | `docker-hub-token` | Docker Hub Personal Access Tokens (`dckr_pat_...`) | High |
|
|
68
|
+
| ๐ Infrastructure | `database-connection-string` | Database Connection Strings (MongoDB, PostgreSQL, MySQL, Redis with credentials) | High |
|
|
69
|
+
| ๐ Infrastructure | `smtp-credentials` | SMTP / SendGrid / Mailgun email passwords | High |
|
|
70
|
+
| ๐ Infrastructure | `terraform-helm-secret` | Terraform (`tf_var_...`) and Helm (`helm_var_...`) variable secrets | High |
|
|
71
|
+
| ๐ Webhooks | `stripe-secret` | Stripe Secret Keys and Webhook Secrets (`sk_live_`, `whsec_`) | High |
|
|
72
|
+
| ๐ Webhooks | `paypal-secret` | PayPal Client Secrets | High |
|
|
73
|
+
| ๐ Webhooks | `generic-webhook` | Generic Webhook URLs (Slack, Discord, IFTTT) | High |
|
|
74
|
+
| ๐ Private Keys | `rsa-private-key` | RSA Private Key blocks (`-----BEGIN RSA PRIVATE KEY-----`) | High |
|
|
75
|
+
| ๐ Private Keys | `dsa-private-key` | DSA Private Key blocks | High |
|
|
76
|
+
| ๐ Private Keys | `ec-private-key` | EC Private Key blocks | High |
|
|
77
|
+
| ๐ Private Keys | `openssh-private-key` | OpenSSH Private Key blocks | High |
|
|
78
|
+
| ๐ Private Keys | `pgp-private-key` | PGP Private Key blocks | High |
|
|
79
|
+
| ๐ Certificates | `banned-file-type` | Banned file extensions: `.pem`, `.key`, `.p12`, `.pfx`, `.crt`, `.cer`, `.keystore`, `.sqlite`, `.db`, `.log`, `.env` | Medium |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## ๐ก๏ธ Intelligent Dummy Detection
|
|
84
|
+
|
|
85
|
+
The scanner features an **Intelligent Ignore System** that automatically downgrades the severity of fake, dummy, or test secrets commonly used in unit tests and example files. This avoids blocking your commits with false positives.
|
|
86
|
+
|
|
87
|
+
**Patterns recognized as dummy:**
|
|
88
|
+
- Sequential characters: `1234567890abcdef`, `abcdefghijklmnop`
|
|
89
|
+
- Common placeholders: `EXAMPLE`, `dummy`, `test`, `fake`, `placeholder`
|
|
90
|
+
- Repetitive patterns: `aaaa`, `0000`
|
|
64
91
|
|
|
65
|
-
|
|
92
|
+
When a dummy value is detected, the finding is downgraded from `โ HIGH` to `โ IGNORED (DUMMY)` and **will not block** your commit.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Severity Levels
|
|
66
97
|
|
|
67
98
|
| Indicator | Level | Color | Meaning |
|
|
68
99
|
|-----------|-------|-------|---------|
|
|
69
|
-
| `โ` |
|
|
70
|
-
| `โ` |
|
|
71
|
-
|
|
|
100
|
+
| `โ` | CRITICAL | Red | CI/CD and service account secrets that grant admin-level access |
|
|
101
|
+
| `โ` | HIGH | Red | Hardcoded secrets that pose a critical risk and must be removed |
|
|
102
|
+
| `โ` | MEDIUM | Yellow | Risky files or configurations not safely ignored in `.gitignore` |
|
|
103
|
+
| `โ` | IGNORED | Dim | Test/example values (auto-detected dummy values that pose no risk) |
|
|
72
104
|
|
|
73
105
|
---
|
|
74
106
|
|
|
75
107
|
## Example Output
|
|
76
108
|
|
|
77
109
|
```
|
|
78
|
-
โ Found
|
|
110
|
+
โ Found 3 potential vulnerabilities! (3 blockers)
|
|
79
111
|
|
|
80
112
|
Scan Results:
|
|
81
113
|
|
|
82
|
-
โ HIGH ยท
|
|
83
|
-
File: src/config/
|
|
84
|
-
Match:
|
|
85
|
-
Risk:
|
|
114
|
+
โ HIGH ยท jwt-secret
|
|
115
|
+
File: src/config/auth.ts:5
|
|
116
|
+
Match: JWT_SECRET=xJk9Lp2Rm5Qw8Yz1Xv4Bn7Cm...
|
|
117
|
+
Risk: An attacker can forge JWT tokens to impersonate any user, including admins.
|
|
86
118
|
|
|
87
119
|
โ HIGH ยท database-connection-string
|
|
88
|
-
File: src/db/connection.ts:
|
|
89
|
-
Match: mongodb+srv://admin:
|
|
90
|
-
Risk: An attacker can directly connect to your database instance
|
|
120
|
+
File: src/db/connection.ts:3
|
|
121
|
+
Match: mongodb+srv://admin:supersecret@cluster0.mongo...
|
|
122
|
+
Risk: An attacker can directly connect to your database instance.
|
|
123
|
+
|
|
124
|
+
โ IGNORED (DUMMY) ยท aws-access-key
|
|
125
|
+
File: tests/mock.ts:10
|
|
126
|
+
Match: AKIAIOSFODNN7EXAMPLE...
|
|
127
|
+
Risk: (auto-downgraded โ recognized as a test/example value)
|
|
91
128
|
```
|
|
92
129
|
|
|
93
130
|
---
|
|
94
131
|
|
|
95
|
-
## Running Tests
|
|
96
|
-
|
|
97
|
-
If you are contributing to the project, you can run the test suite using Vitest:
|
|
132
|
+
## Running Tests
|
|
98
133
|
|
|
99
134
|
```bash
|
|
100
135
|
npm test
|