code-secret-handler 1.0.0

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.
Files changed (171) hide show
  1. package/LICENSE +79 -0
  2. package/README.md +221 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +121 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/env/envWriter.d.ts +9 -0
  8. package/dist/env/envWriter.d.ts.map +1 -0
  9. package/dist/env/envWriter.js +76 -0
  10. package/dist/env/envWriter.js.map +1 -0
  11. package/dist/env/keyNamer.d.ts +13 -0
  12. package/dist/env/keyNamer.d.ts.map +1 -0
  13. package/dist/env/keyNamer.js +33 -0
  14. package/dist/env/keyNamer.js.map +1 -0
  15. package/dist/interactive/confirm.d.ts +16 -0
  16. package/dist/interactive/confirm.d.ts.map +1 -0
  17. package/dist/interactive/confirm.js +72 -0
  18. package/dist/interactive/confirm.js.map +1 -0
  19. package/dist/license/gitContext.d.ts +16 -0
  20. package/dist/license/gitContext.d.ts.map +1 -0
  21. package/dist/license/gitContext.js +117 -0
  22. package/dist/license/gitContext.js.map +1 -0
  23. package/dist/license/licenseCheck.d.ts +22 -0
  24. package/dist/license/licenseCheck.d.ts.map +1 -0
  25. package/dist/license/licenseCheck.js +119 -0
  26. package/dist/license/licenseCheck.js.map +1 -0
  27. package/dist/license/telemetry.d.ts +17 -0
  28. package/dist/license/telemetry.d.ts.map +1 -0
  29. package/dist/license/telemetry.js +87 -0
  30. package/dist/license/telemetry.js.map +1 -0
  31. package/dist/reporter/console.d.ts +3 -0
  32. package/dist/reporter/console.d.ts.map +1 -0
  33. package/dist/reporter/console.js +96 -0
  34. package/dist/reporter/console.js.map +1 -0
  35. package/dist/reporter/csv.d.ts +6 -0
  36. package/dist/reporter/csv.d.ts.map +1 -0
  37. package/dist/reporter/csv.js +56 -0
  38. package/dist/reporter/csv.js.map +1 -0
  39. package/dist/reporter/index.d.ts +13 -0
  40. package/dist/reporter/index.d.ts.map +1 -0
  41. package/dist/reporter/index.js +52 -0
  42. package/dist/reporter/index.js.map +1 -0
  43. package/dist/reporter/json.d.ts +7 -0
  44. package/dist/reporter/json.d.ts.map +1 -0
  45. package/dist/reporter/json.js +39 -0
  46. package/dist/reporter/json.js.map +1 -0
  47. package/dist/reporter/markdown.d.ts +6 -0
  48. package/dist/reporter/markdown.d.ts.map +1 -0
  49. package/dist/reporter/markdown.js +106 -0
  50. package/dist/reporter/markdown.js.map +1 -0
  51. package/dist/rewriter/index.d.ts +9 -0
  52. package/dist/rewriter/index.d.ts.map +1 -0
  53. package/dist/rewriter/index.js +95 -0
  54. package/dist/rewriter/index.js.map +1 -0
  55. package/dist/rewriter/langDetector.d.ts +7 -0
  56. package/dist/rewriter/langDetector.d.ts.map +1 -0
  57. package/dist/rewriter/langDetector.js +96 -0
  58. package/dist/rewriter/langDetector.js.map +1 -0
  59. package/dist/rewriter/templates/csharp.d.ts +8 -0
  60. package/dist/rewriter/templates/csharp.d.ts.map +1 -0
  61. package/dist/rewriter/templates/csharp.js +36 -0
  62. package/dist/rewriter/templates/csharp.js.map +1 -0
  63. package/dist/rewriter/templates/generic.d.ts +7 -0
  64. package/dist/rewriter/templates/generic.d.ts.map +1 -0
  65. package/dist/rewriter/templates/generic.js +40 -0
  66. package/dist/rewriter/templates/generic.js.map +1 -0
  67. package/dist/rewriter/templates/go.d.ts +8 -0
  68. package/dist/rewriter/templates/go.d.ts.map +1 -0
  69. package/dist/rewriter/templates/go.js +56 -0
  70. package/dist/rewriter/templates/go.js.map +1 -0
  71. package/dist/rewriter/templates/java.d.ts +7 -0
  72. package/dist/rewriter/templates/java.d.ts.map +1 -0
  73. package/dist/rewriter/templates/java.js +31 -0
  74. package/dist/rewriter/templates/java.js.map +1 -0
  75. package/dist/rewriter/templates/javascript.d.ts +10 -0
  76. package/dist/rewriter/templates/javascript.d.ts.map +1 -0
  77. package/dist/rewriter/templates/javascript.js +54 -0
  78. package/dist/rewriter/templates/javascript.js.map +1 -0
  79. package/dist/rewriter/templates/php.d.ts +8 -0
  80. package/dist/rewriter/templates/php.d.ts.map +1 -0
  81. package/dist/rewriter/templates/php.js +41 -0
  82. package/dist/rewriter/templates/php.js.map +1 -0
  83. package/dist/rewriter/templates/properties.d.ts +9 -0
  84. package/dist/rewriter/templates/properties.d.ts.map +1 -0
  85. package/dist/rewriter/templates/properties.js +39 -0
  86. package/dist/rewriter/templates/properties.js.map +1 -0
  87. package/dist/rewriter/templates/python.d.ts +8 -0
  88. package/dist/rewriter/templates/python.d.ts.map +1 -0
  89. package/dist/rewriter/templates/python.js +48 -0
  90. package/dist/rewriter/templates/python.js.map +1 -0
  91. package/dist/rewriter/templates/ruby.d.ts +8 -0
  92. package/dist/rewriter/templates/ruby.d.ts.map +1 -0
  93. package/dist/rewriter/templates/ruby.js +40 -0
  94. package/dist/rewriter/templates/ruby.js.map +1 -0
  95. package/dist/rewriter/templates/rust.d.ts +7 -0
  96. package/dist/rewriter/templates/rust.d.ts.map +1 -0
  97. package/dist/rewriter/templates/rust.js +27 -0
  98. package/dist/rewriter/templates/rust.js.map +1 -0
  99. package/dist/rewriter/templates/shell.d.ts +7 -0
  100. package/dist/rewriter/templates/shell.d.ts.map +1 -0
  101. package/dist/rewriter/templates/shell.js +42 -0
  102. package/dist/rewriter/templates/shell.js.map +1 -0
  103. package/dist/rewriter/templates/toml.d.ts +9 -0
  104. package/dist/rewriter/templates/toml.d.ts.map +1 -0
  105. package/dist/rewriter/templates/toml.js +34 -0
  106. package/dist/rewriter/templates/toml.js.map +1 -0
  107. package/dist/rewriter/templates/yaml.d.ts +8 -0
  108. package/dist/rewriter/templates/yaml.d.ts.map +1 -0
  109. package/dist/rewriter/templates/yaml.js +37 -0
  110. package/dist/rewriter/templates/yaml.js.map +1 -0
  111. package/dist/scanner/detector.d.ts +18 -0
  112. package/dist/scanner/detector.d.ts.map +1 -0
  113. package/dist/scanner/detector.js +156 -0
  114. package/dist/scanner/detector.js.map +1 -0
  115. package/dist/scanner/fileWalker.d.ts +6 -0
  116. package/dist/scanner/fileWalker.d.ts.map +1 -0
  117. package/dist/scanner/fileWalker.js +146 -0
  118. package/dist/scanner/fileWalker.js.map +1 -0
  119. package/dist/scanner/index.d.ts +8 -0
  120. package/dist/scanner/index.d.ts.map +1 -0
  121. package/dist/scanner/index.js +74 -0
  122. package/dist/scanner/index.js.map +1 -0
  123. package/dist/scanner/rules/aws.d.ts +6 -0
  124. package/dist/scanner/rules/aws.d.ts.map +1 -0
  125. package/dist/scanner/rules/aws.js +90 -0
  126. package/dist/scanner/rules/aws.js.map +1 -0
  127. package/dist/scanner/rules/azure.d.ts +6 -0
  128. package/dist/scanner/rules/azure.d.ts.map +1 -0
  129. package/dist/scanner/rules/azure.js +86 -0
  130. package/dist/scanner/rules/azure.js.map +1 -0
  131. package/dist/scanner/rules/cloud.d.ts +11 -0
  132. package/dist/scanner/rules/cloud.d.ts.map +1 -0
  133. package/dist/scanner/rules/cloud.js +1066 -0
  134. package/dist/scanner/rules/cloud.js.map +1 -0
  135. package/dist/scanner/rules/database.d.ts +6 -0
  136. package/dist/scanner/rules/database.d.ts.map +1 -0
  137. package/dist/scanner/rules/database.js +283 -0
  138. package/dist/scanner/rules/database.js.map +1 -0
  139. package/dist/scanner/rules/gcp.d.ts +6 -0
  140. package/dist/scanner/rules/gcp.d.ts.map +1 -0
  141. package/dist/scanner/rules/gcp.js +108 -0
  142. package/dist/scanner/rules/gcp.js.map +1 -0
  143. package/dist/scanner/rules/generic.d.ts +13 -0
  144. package/dist/scanner/rules/generic.d.ts.map +1 -0
  145. package/dist/scanner/rules/generic.js +305 -0
  146. package/dist/scanner/rules/generic.js.map +1 -0
  147. package/dist/scanner/rules/index.d.ts +18 -0
  148. package/dist/scanner/rules/index.d.ts.map +1 -0
  149. package/dist/scanner/rules/index.js +40 -0
  150. package/dist/scanner/rules/index.js.map +1 -0
  151. package/dist/scanner/rules/jwt.d.ts +6 -0
  152. package/dist/scanner/rules/jwt.d.ts.map +1 -0
  153. package/dist/scanner/rules/jwt.js +97 -0
  154. package/dist/scanner/rules/jwt.js.map +1 -0
  155. package/dist/scanner/rules/network.d.ts +7 -0
  156. package/dist/scanner/rules/network.d.ts.map +1 -0
  157. package/dist/scanner/rules/network.js +166 -0
  158. package/dist/scanner/rules/network.js.map +1 -0
  159. package/dist/scanner/rules/privateKey.d.ts +6 -0
  160. package/dist/scanner/rules/privateKey.d.ts.map +1 -0
  161. package/dist/scanner/rules/privateKey.js +60 -0
  162. package/dist/scanner/rules/privateKey.js.map +1 -0
  163. package/dist/scanner/rules/ssh.d.ts +6 -0
  164. package/dist/scanner/rules/ssh.d.ts.map +1 -0
  165. package/dist/scanner/rules/ssh.js +49 -0
  166. package/dist/scanner/rules/ssh.js.map +1 -0
  167. package/dist/types.d.ts +78 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +3 -0
  170. package/dist/types.js.map +1 -0
  171. package/package.json +54 -0
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.networkRules = void 0;
4
+ /**
5
+ * Network, infrastructure, and communication credential patterns.
6
+ * Covers: SMTP, proxy, VPN, Twilio SMS, mail servers, webhooks, etc.
7
+ */
8
+ exports.networkRules = [
9
+ // ── SMTP / Email server ─────────────────────────────────────────────────────────
10
+ {
11
+ id: 'smtp-password',
12
+ description: 'SMTP server password or auth credentials',
13
+ pattern: /(?:smtp[_-]?(?:pass(?:word)?|auth[_-]?pass(?:word)?)|SMTP_PASSWORD|MAIL_PASSWORD|EMAIL_PASSWORD)\s*[:=]\s*['"\`]([^'"\`\n]{4,})['"\`]/i,
14
+ valueGroup: 1,
15
+ envKeyPrefix: 'SMTP_PASSWORD',
16
+ severity: 'critical',
17
+ },
18
+ {
19
+ id: 'smtp-uri',
20
+ description: 'SMTP URI with embedded credentials',
21
+ pattern: /(?:smtp[_-]?(?:url|uri)|SMTP_URL|EMAIL_SERVER|MAIL_URL)\s*[:=]\s*['"\`](smtps?:\/\/[^'"\`\s]+:[^'"\`\s]+@[^'"\`\s]+)['"\`]/i,
22
+ valueGroup: 1,
23
+ envKeyPrefix: 'SMTP_URL',
24
+ severity: 'critical',
25
+ },
26
+ {
27
+ id: 'smtp-user',
28
+ description: 'SMTP username assignment',
29
+ pattern: /(?:smtp[_-]?user(?:name)?|SMTP_USER(?:NAME)?|MAIL_USER(?:NAME)?|EMAIL_USER(?:NAME)?)\s*[:=]\s*['"\`]([^'"\`\n]{2,})['"\`]/i,
30
+ valueGroup: 1,
31
+ envKeyPrefix: 'SMTP_USER',
32
+ severity: 'medium',
33
+ },
34
+ // ── Proxy / VPN ───────────────────────────────────────────────────────────────
35
+ {
36
+ id: 'proxy-url-with-creds',
37
+ description: 'Proxy URL with embedded username/password',
38
+ pattern: /(?:http[s]?[_-]?proxy|proxy[_-]?url|HTTPS?_PROXY|ALL_PROXY)\s*[:=]\s*['"\`](https?:\/\/[^'"\`\s]+:[^'"\`\s]+@[^'"\`\s]+)['"\`]/i,
39
+ valueGroup: 1,
40
+ envKeyPrefix: 'PROXY_URL',
41
+ severity: 'critical',
42
+ },
43
+ {
44
+ id: 'proxy-password',
45
+ description: 'Proxy server password',
46
+ pattern: /(?:proxy[_-]?pass(?:word)?|PROXY_PASSWORD)\s*[:=]\s*['"\`]([^'"\`\n]{4,})['"\`]/i,
47
+ valueGroup: 1,
48
+ envKeyPrefix: 'PROXY_PASSWORD',
49
+ severity: 'critical',
50
+ },
51
+ // ── CI/CD secrets ──────────────────────────────────────────────────────────────
52
+ {
53
+ id: 'ci-deploy-token',
54
+ description: 'CI/CD deploy token or secret',
55
+ pattern: /(?:ci[_-]?(?:deploy[_-]?)?(?:token|secret|key)|deploy[_-]?(?:token|key|secret)|DEPLOY_TOKEN|CI_DEPLOY_TOKEN)\s*[:=]\s*['"\`]([A-Za-z0-9\-_]{16,})['"\`]/i,
56
+ valueGroup: 1,
57
+ envKeyPrefix: 'DEPLOY_TOKEN',
58
+ severity: 'critical',
59
+ },
60
+ {
61
+ id: 'github-actions-secret',
62
+ description: 'GitHub Actions secret reference used as a hardcoded value',
63
+ pattern: /(?:ACTIONS_RUNNER_TOKEN|ACTIONS_ID_TOKEN_REQUEST_TOKEN|ACTIONS_RUNTIME_TOKEN)\s*[:=]\s*['"\`]([A-Za-z0-9+/=]{20,})['"\`]/,
64
+ valueGroup: 1,
65
+ envKeyPrefix: 'GITHUB_ACTIONS_TOKEN',
66
+ severity: 'critical',
67
+ },
68
+ // ── Apple / iOS ───────────────────────────────────────────────────────────────
69
+ {
70
+ id: 'apple-private-key-id',
71
+ description: 'Apple APNs / App Store Connect Private Key ID',
72
+ pattern: /(?:apple[_-]?(?:private[_-]?)?key[_-]?id|APPLE_KEY_ID|APP_STORE_CONNECT_KEY_ID)\s*[:=]\s*['"\`]([A-Z0-9]{10})['"\`]/i,
73
+ valueGroup: 1,
74
+ envKeyPrefix: 'APPLE_KEY_ID',
75
+ severity: 'high',
76
+ },
77
+ {
78
+ id: 'apple-team-id',
79
+ description: 'Apple Developer Team ID',
80
+ pattern: /(?:apple[_-]?team[_-]?id|APPLE_TEAM_ID|TEAM_ID)\s*[:=]\s*['"\`]([A-Z0-9]{10})['"\`]/i,
81
+ valueGroup: 1,
82
+ envKeyPrefix: 'APPLE_TEAM_ID',
83
+ severity: 'medium',
84
+ },
85
+ // ── Webhook URLs (generic) ─────────────────────────────────────────────────────
86
+ {
87
+ id: 'generic-webhook-url',
88
+ description: 'Hardcoded webhook URL with embedded token',
89
+ pattern: /(?:webhook[_-]?url|WEBHOOK_URL)\s*[:=]\s*['"\`](https?:\/\/[^'"\`\s]{20,})['"\`]/i,
90
+ valueGroup: 1,
91
+ envKeyPrefix: 'WEBHOOK_URL',
92
+ severity: 'high',
93
+ },
94
+ // ── LDAP credentials ───────────────────────────────────────────────────────────
95
+ {
96
+ id: 'ldap-bind-password',
97
+ description: 'LDAP bind password',
98
+ pattern: /(?:ldap[_-]?(?:bind[_-]?)?pass(?:word)?|LDAP_BIND_PASSWORD|LDAP_PASSWORD)\s*[:=]\s*['"\`]([^'"\`\n]{4,})['"\`]/i,
99
+ valueGroup: 1,
100
+ envKeyPrefix: 'LDAP_PASSWORD',
101
+ severity: 'critical',
102
+ },
103
+ {
104
+ id: 'ldap-uri',
105
+ description: 'LDAP connection URI',
106
+ pattern: /(?:ldap[_-]?(?:url|uri)|LDAP_URL|LDAP_URI)\s*[:=]\s*['"\`](ldaps?:\/\/[^'"\`\s]+)['"\`]/i,
107
+ valueGroup: 1,
108
+ envKeyPrefix: 'LDAP_URL',
109
+ severity: 'medium',
110
+ },
111
+ // Kubernetes Service Account Token
112
+ {
113
+ id: 'kubernetes-service-account-token',
114
+ description: 'Kubernetes Service Account Bearer Token (hardcoded JWT)',
115
+ pattern: /(?:k8s[_-]?(?:service[_-]?account[_-]?)?token|kube(?:rnetes)?[_-]?(?:service[_-]?account[_-]?)?token|K8S_TOKEN|KUBE_TOKEN)\s*[:=]\s*['"\`](eyJ[A-Za-z0-9\-_]+\.eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_.+\/=]+)['"\`]/i,
116
+ valueGroup: 1,
117
+ envKeyPrefix: 'K8S_SERVICE_ACCOUNT_TOKEN',
118
+ severity: 'critical',
119
+ },
120
+ // Ansible Vault Password
121
+ {
122
+ id: 'ansible-vault-password',
123
+ description: 'Ansible Vault password variable',
124
+ pattern: /(?:ansible[_-]?vault[_-]?pass(?:word)?|ANSIBLE_VAULT_PASSWORD|vault[_-]?pass(?:word)?)\s*[:=]\s*['"\`]([^'"\`\n]{4,})['"\`]/i,
125
+ valueGroup: 1,
126
+ envKeyPrefix: 'ANSIBLE_VAULT_PASSWORD',
127
+ severity: 'critical',
128
+ },
129
+ // SonarQube / SonarCloud token
130
+ {
131
+ id: 'sonarqube-token',
132
+ description: 'SonarQube or SonarCloud analysis token (squ_ prefix)',
133
+ pattern: /(?:sonar(?:qube|cloud)?[_-]?token|SONAR_TOKEN|SONARQUBE_TOKEN)\s*[:=]\s*['"\`](squ_[A-Za-z0-9]{40,}|[A-Za-z0-9]{40,})['"\`]/i,
134
+ valueGroup: 1,
135
+ envKeyPrefix: 'SONAR_TOKEN',
136
+ severity: 'critical',
137
+ },
138
+ // CircleCI Personal API Token
139
+ {
140
+ id: 'circleci-personal-token',
141
+ description: 'CircleCI Personal API Token',
142
+ pattern: /(?:circleci[_-]?(?:personal[_-]?)?(?:api[_-]?)?token|CIRCLE_TOKEN|CIRCLECI_TOKEN)\s*[:=]\s*['"\`]([a-f0-9]{40})['"\`]/i,
143
+ valueGroup: 1,
144
+ envKeyPrefix: 'CIRCLECI_TOKEN',
145
+ severity: 'critical',
146
+ },
147
+ // ── Jenkins ───────────────────────────────────────────────────────────────────
148
+ {
149
+ id: 'jenkins-api-token',
150
+ description: 'Jenkins User API Token',
151
+ pattern: /(?:jenkins[_-]?(?:api[_-]?)?(?:token|key)|JENKINS_API_TOKEN|JENKINS_TOKEN)\s*[:=]\s*['"`]([A-Za-z0-9]{32,})['"`]/i,
152
+ valueGroup: 1,
153
+ envKeyPrefix: 'JENKINS_API_TOKEN',
154
+ severity: 'critical',
155
+ },
156
+ // ── Travis CI ─────────────────────────────────────────────────────────────────
157
+ {
158
+ id: 'travis-ci-token',
159
+ description: 'Travis CI API Token',
160
+ pattern: /(?:travis[_-]?(?:ci[_-]?)?(?:api[_-]?)?token|TRAVIS_TOKEN|TRAVIS_CI_TOKEN)\s*[:=]\s*['"`]([A-Za-z0-9\-_]{22,})['"`]/i,
161
+ valueGroup: 1,
162
+ envKeyPrefix: 'TRAVIS_CI_TOKEN',
163
+ severity: 'critical',
164
+ },
165
+ ];
166
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/scanner/rules/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Rule } from '../../types';
2
+ /**
3
+ * Generic PEM private key and certificate patterns.
4
+ */
5
+ export declare const privateKeyRules: Rule[];
6
+ //# sourceMappingURL=privateKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privateKey.d.ts","sourceRoot":"","sources":["../../../src/scanner/rules/privateKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,IAAI,EAsDjC,CAAC"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.privateKeyRules = void 0;
4
+ /**
5
+ * Generic PEM private key and certificate patterns.
6
+ */
7
+ exports.privateKeyRules = [
8
+ {
9
+ id: 'pem-private-key',
10
+ description: 'Generic PEM Private Key block',
11
+ pattern: /(-----BEGIN (?:RSA |EC |DSA |OPENSSH |PKCS8 )?PRIVATE KEY-----[\s\S]{64,}-----END (?:RSA |EC |DSA |OPENSSH |PKCS8 )?PRIVATE KEY-----)/,
12
+ valueGroup: 1,
13
+ envKeyPrefix: 'PEM_PRIVATE_KEY',
14
+ severity: 'critical',
15
+ },
16
+ {
17
+ id: 'pem-certificate',
18
+ description: 'PEM Certificate block',
19
+ pattern: /(-----BEGIN CERTIFICATE-----[\s\S]{64,}-----END CERTIFICATE-----)/,
20
+ valueGroup: 1,
21
+ envKeyPrefix: 'PEM_CERTIFICATE',
22
+ severity: 'medium',
23
+ },
24
+ {
25
+ id: 'pgp-private-key',
26
+ description: 'PGP / GPG Private Key Block',
27
+ pattern: /(-----BEGIN PGP PRIVATE KEY BLOCK-----[\s\S]{64,}-----END PGP PRIVATE KEY BLOCK-----)/,
28
+ valueGroup: 1,
29
+ envKeyPrefix: 'PGP_PRIVATE_KEY',
30
+ severity: 'critical',
31
+ },
32
+ {
33
+ id: 'pkcs12-password',
34
+ description: 'PKCS12 / PFX keystore password',
35
+ pattern: /(?:pkcs12[_-]?password|pfx[_-]?password|keystore[_-]?password|KEY_STORE_PASSWORD|PKCS12_PASSWORD)\s*[:=]\s*['"`]([^'"`\n]{4,})['"`]/i,
36
+ valueGroup: 1,
37
+ envKeyPrefix: 'PKCS12_PASSWORD',
38
+ severity: 'critical',
39
+ },
40
+ {
41
+ id: 'ssl-key-path',
42
+ description: 'SSL/TLS private key file path',
43
+ pattern: /(?:ssl[_-]?key(?:[_-]?file)?|tls[_-]?key(?:[_-]?file)?|SSL_KEY_FILE)\s*[:=]\s*['"`]([^'"`\n]+\.(?:key|pem))['"`]/i,
44
+ valueGroup: 1,
45
+ envKeyPrefix: 'SSL_KEY_FILE',
46
+ severity: 'medium',
47
+ },
48
+ // ── age encryption tool secret key ───────────────────────────────────────────
49
+ {
50
+ id: 'age-secret-key',
51
+ description: 'age encryption tool secret key (AGE-SECRET-KEY-1 Bech32 format)',
52
+ // age secret keys are Bech32-encoded and always start with AGE-SECRET-KEY-1
53
+ // followed by 58 uppercase alphanumeric Bech32 chars
54
+ pattern: /(AGE-SECRET-KEY-1[A-Z0-9]{58})/,
55
+ valueGroup: 1,
56
+ envKeyPrefix: 'AGE_SECRET_KEY',
57
+ severity: 'critical',
58
+ },
59
+ ];
60
+ //# sourceMappingURL=privateKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privateKey.js","sourceRoot":"","sources":["../../../src/scanner/rules/privateKey.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,eAAe,GAAW;IACrC;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,+BAA+B;QAC5C,OAAO,EAAE,uIAAuI;QAChJ,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,iBAAiB;QAC/B,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,uBAAuB;QACpC,OAAO,EAAE,mEAAmE;QAC5E,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,iBAAiB;QAC/B,QAAQ,EAAE,QAAQ;KACnB;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,uFAAuF;QAChG,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,iBAAiB;QAC/B,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,WAAW,EAAE,gCAAgC;QAC7C,OAAO,EAAE,sIAAsI;QAC/I,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,iBAAiB;QAC/B,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,cAAc;QAClB,WAAW,EAAE,+BAA+B;QAC5C,OAAO,EAAE,mHAAmH;QAC5H,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,cAAc;QAC5B,QAAQ,EAAE,QAAQ;KACnB;IAED,gFAAgF;IAChF;QACE,EAAE,EAAE,gBAAgB;QACpB,WAAW,EAAE,iEAAiE;QAC9E,4EAA4E;QAC5E,qDAAqD;QACrD,OAAO,EAAE,gCAAgC;QACzC,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,gBAAgB;QAC9B,QAAQ,EAAE,UAAU;KACrB;CAEF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Rule } from '../../types';
2
+ /**
3
+ * SSH and PEM private key patterns.
4
+ */
5
+ export declare const sshRules: Rule[];
6
+ //# sourceMappingURL=ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../../src/scanner/rules/ssh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,IAAI,EAyC1B,CAAC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sshRules = void 0;
4
+ /**
5
+ * SSH and PEM private key patterns.
6
+ */
7
+ exports.sshRules = [
8
+ {
9
+ id: 'ssh-private-key-pem',
10
+ description: 'SSH RSA Private Key (PEM block)',
11
+ pattern: /(-----BEGIN RSA PRIVATE KEY-----[\s\S]{64,}-----END RSA PRIVATE KEY-----)/,
12
+ valueGroup: 1,
13
+ envKeyPrefix: 'SSH_RSA_PRIVATE_KEY',
14
+ severity: 'critical',
15
+ },
16
+ {
17
+ id: 'ssh-openssh-private-key',
18
+ description: 'OpenSSH Private Key',
19
+ pattern: /(-----BEGIN OPENSSH PRIVATE KEY-----[\s\S]{64,}-----END OPENSSH PRIVATE KEY-----)/,
20
+ valueGroup: 1,
21
+ envKeyPrefix: 'SSH_OPENSSH_PRIVATE_KEY',
22
+ severity: 'critical',
23
+ },
24
+ {
25
+ id: 'ssh-dsa-private-key',
26
+ description: 'SSH DSA Private Key (PEM block)',
27
+ pattern: /(-----BEGIN DSA PRIVATE KEY-----[\s\S]{64,}-----END DSA PRIVATE KEY-----)/,
28
+ valueGroup: 1,
29
+ envKeyPrefix: 'SSH_DSA_PRIVATE_KEY',
30
+ severity: 'critical',
31
+ },
32
+ {
33
+ id: 'ssh-ec-private-key',
34
+ description: 'SSH EC Private Key (PEM block)',
35
+ pattern: /(-----BEGIN EC PRIVATE KEY-----[\s\S]{64,}-----END EC PRIVATE KEY-----)/,
36
+ valueGroup: 1,
37
+ envKeyPrefix: 'SSH_EC_PRIVATE_KEY',
38
+ severity: 'critical',
39
+ },
40
+ {
41
+ id: 'ssh-private-key-inline',
42
+ description: 'SSH private key assigned as an inline string variable',
43
+ pattern: /(?:ssh[_-]?private[_-]?key|SSH_PRIVATE_KEY|id_rsa)\s*[:=]\s*['"`](-----BEGIN[^'"`]+-----END[^'"`]+-----)['"`]/i,
44
+ valueGroup: 1,
45
+ envKeyPrefix: 'SSH_PRIVATE_KEY',
46
+ severity: 'critical',
47
+ },
48
+ ];
49
+ //# sourceMappingURL=ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../../src/scanner/rules/ssh.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,QAAQ,GAAW;IAC9B;QACE,EAAE,EAAE,qBAAqB;QACzB,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,2EAA2E;QACpF,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,qBAAqB;QACnC,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,mFAAmF;QAC5F,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,yBAAyB;QACvC,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,2EAA2E;QACpF,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,qBAAqB;QACnC,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,WAAW,EAAE,gCAAgC;QAC7C,OAAO,EAAE,yEAAyE;QAClF,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,oBAAoB;QAClC,QAAQ,EAAE,UAAU;KACrB;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,gHAAgH;QACzH,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,iBAAiB;QAC/B,QAAQ,EAAE,UAAU;KACrB;CACF,CAAC"}
@@ -0,0 +1,78 @@
1
+ export type Severity = 'critical' | 'high' | 'medium' | 'low';
2
+ export type ReportFormat = 'console' | 'json' | 'csv' | 'markdown';
3
+ export interface Rule {
4
+ /** Unique rule identifier, e.g. "aws-access-key" */
5
+ id: string;
6
+ /** Human-readable description */
7
+ description: string;
8
+ /**
9
+ * Regex that matches the whole assignment / value line.
10
+ * Must have at least one capture group for the secret value.
11
+ */
12
+ pattern: RegExp;
13
+ /** Index of the capture group that contains the raw secret value (1-based) */
14
+ valueGroup: number;
15
+ /** Prefix used when auto-generating the env var name, e.g. "AWS_ACCESS_KEY" */
16
+ envKeyPrefix: string;
17
+ /** Severity classification */
18
+ severity: Severity;
19
+ }
20
+ export interface Finding {
21
+ /** Absolute path to the source file */
22
+ file: string;
23
+ /** 1-based line number */
24
+ line: number;
25
+ /** 1-based column where the secret value starts */
26
+ column: number;
27
+ /** The rule that triggered this finding */
28
+ rule: Rule;
29
+ /** The raw secret value extracted from source */
30
+ rawValue: string;
31
+ /** The full matched line (for context) */
32
+ lineContent: string;
33
+ /** Generated env var name (set after deduplication) */
34
+ envKey: string;
35
+ /** Whether this finding was already present in the .env file */
36
+ alreadyInEnv?: boolean;
37
+ }
38
+ export interface CliOptions {
39
+ /** Directory to scan (default: cwd) */
40
+ targetDir: string;
41
+ /** Report output format */
42
+ report: ReportFormat;
43
+ /** Report output file path (auto-derived if omitted) */
44
+ output?: string;
45
+ /** Path to .env file (default: <targetDir>/.env) */
46
+ envFile: string;
47
+ /** Scan only — do not write any files */
48
+ dryRun: boolean;
49
+ /** Write .env but skip source-file rewriting */
50
+ noRewrite: boolean;
51
+ }
52
+ export type Language = 'javascript' | 'typescript' | 'python' | 'java' | 'go' | 'ruby' | 'php' | 'csharp' | 'rust' | 'shell' | 'yaml' | 'toml' | 'properties' | 'generic';
53
+ export interface RewriteContext {
54
+ finding: Finding;
55
+ language: Language;
56
+ fileContent: string;
57
+ }
58
+ export interface RewriteResult {
59
+ filePath: string;
60
+ originalContent: string;
61
+ rewrittenContent: string;
62
+ /** Number of replacements made */
63
+ replacements: number;
64
+ /** Whether a dotenv import/require was injected */
65
+ dotenvInjected: boolean;
66
+ }
67
+ export interface ScanSummary {
68
+ targetDir: string;
69
+ filesScanned: number;
70
+ filesWithSecrets: number;
71
+ totalFindings: number;
72
+ findings: Finding[];
73
+ envFile: string;
74
+ reportFile?: string;
75
+ dryRun: boolean;
76
+ scannedAt: string;
77
+ }
78
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAG9D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;AAGnE,MAAM,WAAW,IAAI;IACnB,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAGD,MAAM,WAAW,OAAO;IACtB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,IAAI,CAAC;IACX,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAGD,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,MAAM,GACN,IAAI,GACJ,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,YAAY,GACZ,SAAS,CAAC;AAGd,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,cAAc,EAAE,OAAO,CAAC;CACzB;AAGD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "code-secret-handler",
3
+ "version": "1.0.0",
4
+ "description": "A language-agnostic CLI tool that scans codebases for hardcoded secrets, moves them to .env files, and rewrites source files with proper env-var references.",
5
+ "main": "dist/cli.js",
6
+ "bin": {
7
+ "code-secret-handler": "./dist/cli.js",
8
+ "csh": "./dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "tsx src/cli.ts",
13
+ "dev": "tsx src/cli.ts",
14
+ "lint": "tsc --noEmit",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git@github-vic:vic-grambo/code-secret-handler.git"
20
+ },
21
+ "keywords": [
22
+ "security",
23
+ "secrets",
24
+ "scanner",
25
+ "hardcoded",
26
+ "env",
27
+ "dotenv",
28
+ "cli",
29
+ "devops"
30
+ ],
31
+ "author": "Vic <vic.grambo@gmail.com>",
32
+ "license": "PolyForm-Noncommercial-1.0.0",
33
+ "files": [
34
+ "dist",
35
+ "LICENSE",
36
+ "README.md"
37
+ ],
38
+ "type": "commonjs",
39
+ "dependencies": {
40
+ "chalk": "^6.0.0",
41
+ "commander": "^15.0.0",
42
+ "fast-glob": "^3.3.3",
43
+ "ignore": "^7.0.10",
44
+ "inquirer": "^14.2.2",
45
+ "ora": "^9.4.1"
46
+ },
47
+ "devDependencies": {
48
+ "@types/glob": "^8.1.0",
49
+ "@types/inquirer": "^9.0.10",
50
+ "@types/node": "^26.6.2",
51
+ "tsx": "^4.23.15",
52
+ "typescript": "^7.0.2"
53
+ }
54
+ }