@westbayberry/dg 1.3.3 → 2.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.
- package/LICENSE +1 -201
- package/NOTICE +1 -4
- package/README.md +293 -0
- package/dist/api/analyze.js +210 -0
- package/dist/audit/deep.js +180 -0
- package/dist/audit/detectors.js +247 -0
- package/dist/audit/events.js +41 -0
- package/dist/audit/rules.js +426 -0
- package/dist/audit-ui/AuditApp.js +39 -0
- package/dist/audit-ui/components/AuditHeader.js +24 -0
- package/dist/audit-ui/components/AuditResultsView.js +307 -0
- package/dist/audit-ui/components/DeepStatusRow.js +11 -0
- package/dist/audit-ui/export.js +85 -0
- package/dist/audit-ui/format.js +34 -0
- package/dist/audit-ui/launch.js +34 -0
- package/dist/auth/device-login.js +271 -0
- package/dist/auth/env-token.js +6 -0
- package/dist/auth/login-app.js +156 -0
- package/dist/auth/store.js +147 -0
- package/dist/bin/dg.js +71 -0
- package/dist/commands/audit.js +357 -0
- package/dist/commands/completion.js +116 -0
- package/dist/commands/config.js +99 -0
- package/dist/commands/doctor.js +39 -0
- package/dist/commands/explain.js +100 -0
- package/dist/commands/guard-commit.js +158 -0
- package/dist/commands/help.js +74 -0
- package/dist/commands/licenses.js +435 -0
- package/dist/commands/login.js +81 -0
- package/dist/commands/logout.js +37 -0
- package/dist/commands/router.js +98 -0
- package/dist/commands/scan.js +18 -0
- package/dist/commands/service.js +475 -0
- package/dist/commands/setup.js +302 -0
- package/dist/commands/status.js +115 -0
- package/dist/commands/suggest.js +35 -0
- package/dist/commands/types.js +4 -0
- package/dist/commands/unavailable.js +11 -0
- package/dist/commands/uninstall.js +111 -0
- package/dist/commands/update.js +210 -0
- package/dist/commands/verify.js +151 -0
- package/dist/commands/version.js +22 -0
- package/dist/commands/wrap.js +55 -0
- package/dist/config/settings.js +302 -0
- package/dist/install-ui/LiveInstall.js +24 -0
- package/dist/install-ui/block-render.js +83 -0
- package/dist/install-ui/live-install-app.js +48 -0
- package/dist/install-ui/prompt.js +24 -0
- package/dist/launcher/classify.js +116 -0
- package/dist/launcher/env.js +53 -0
- package/dist/launcher/live-install.js +50 -0
- package/dist/launcher/output-redaction.js +77 -0
- package/dist/launcher/preflight-prompt.js +139 -0
- package/dist/launcher/resolve-real-binary.js +73 -0
- package/dist/launcher/run.js +417 -0
- package/dist/policy/evaluate.js +128 -0
- package/dist/presentation/mode.js +52 -0
- package/dist/presentation/theme.js +29 -0
- package/dist/proxy/buffer-budget.js +64 -0
- package/dist/proxy/ca.js +126 -0
- package/dist/proxy/classify-host.js +26 -0
- package/dist/proxy/enforcement.js +102 -0
- package/dist/proxy/metadata-map.js +336 -0
- package/dist/proxy/server.js +909 -0
- package/dist/proxy/upstream-proxy.js +102 -0
- package/dist/proxy/worker.js +39 -0
- package/dist/publish-set/collect.js +51 -0
- package/dist/publish-set/no-exec-shell.js +19 -0
- package/dist/publish-set/npm.js +109 -0
- package/dist/publish-set/pack.js +36 -0
- package/dist/publish-set/pypi.js +59 -0
- package/dist/runtime/cli.js +17 -0
- package/dist/runtime/first-run.js +60 -0
- package/dist/runtime/node-version.js +58 -0
- package/dist/runtime/nudges.js +105 -0
- package/dist/scan/analyze-worker.js +21 -0
- package/dist/scan/collect.js +153 -0
- package/dist/scan/command.js +159 -0
- package/dist/scan/discovery.js +209 -0
- package/dist/scan/render.js +240 -0
- package/dist/scan/scanner-report.js +82 -0
- package/dist/scan/staged.js +173 -0
- package/dist/scan/types.js +1 -0
- package/dist/scan-ui/LegacyApp.js +156 -0
- package/dist/scan-ui/alt-screen.js +84 -0
- package/dist/scan-ui/api-aliases.js +1 -0
- package/dist/scan-ui/components/ErrorView.js +23 -0
- package/dist/scan-ui/components/InteractiveResultsView.js +1166 -0
- package/dist/scan-ui/components/ProgressBar.js +89 -0
- package/dist/scan-ui/components/ProjectSelector.js +62 -0
- package/dist/scan-ui/components/ScoreHeader.js +20 -0
- package/dist/scan-ui/components/SetupBanner.js +13 -0
- package/dist/scan-ui/components/Spinner.js +4 -0
- package/dist/scan-ui/format-helpers.js +40 -0
- package/dist/scan-ui/hooks/useExpandAnimation.js +40 -0
- package/dist/scan-ui/hooks/useScan.js +113 -0
- package/dist/scan-ui/hooks/useTerminalSize.js +24 -0
- package/dist/scan-ui/launch.js +27 -0
- package/dist/scan-ui/logo.js +91 -0
- package/dist/scan-ui/shims.js +30 -0
- package/dist/security/sanitize.js +28 -0
- package/dist/service/state.js +837 -0
- package/dist/service/trust-store.js +234 -0
- package/dist/service/worker.js +88 -0
- package/dist/setup/git-hook.js +244 -0
- package/dist/setup/optional-support.js +58 -0
- package/dist/setup/plan.js +899 -0
- package/dist/state/cleanup-registry.js +60 -0
- package/dist/state/index.js +5 -0
- package/dist/state/locks.js +161 -0
- package/dist/state/paths.js +24 -0
- package/dist/state/sessions.js +170 -0
- package/dist/state/store.js +50 -0
- package/dist/telemetry/events.js +40 -0
- package/dist/util/git.js +20 -0
- package/dist/util/tty-prompt.js +43 -0
- package/dist/verify/local.js +400 -0
- package/dist/verify/package-check.js +240 -0
- package/dist/verify/preflight.js +698 -0
- package/dist/verify/render.js +184 -0
- package/dist/verify/types.js +1 -0
- package/package.json +33 -50
- package/dist/index.mjs +0 -54116
- package/dist/postinstall.mjs +0 -731
- package/dist/python-hook/dg_pip_hook.pth +0 -1
- package/dist/python-hook/dg_pip_hook.py +0 -130
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
export const FILENAME_RULES = [
|
|
2
|
+
{
|
|
3
|
+
id: "env-file",
|
|
4
|
+
re: /(^|\/)\.env(\.[^/]+)?$/iu,
|
|
5
|
+
exempt: /\.env\.(example|sample|template|dist|defaults?)$/iu,
|
|
6
|
+
category: "credential-file",
|
|
7
|
+
severity: 4,
|
|
8
|
+
title: "Environment file bundled in publish payload",
|
|
9
|
+
recommendation: "Exclude .env files and rotate any exposed secrets."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "npmrc",
|
|
13
|
+
re: /(^|\/)\.npmrc$/iu,
|
|
14
|
+
category: "credential-file",
|
|
15
|
+
severity: 5,
|
|
16
|
+
title: ".npmrc bundled in publish payload",
|
|
17
|
+
recommendation: "Remove .npmrc and revoke any registry token it contained."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "pypirc",
|
|
21
|
+
re: /(^|\/)\.pypirc$/iu,
|
|
22
|
+
category: "credential-file",
|
|
23
|
+
severity: 5,
|
|
24
|
+
title: ".pypirc bundled in publish payload",
|
|
25
|
+
recommendation: "Remove .pypirc and revoke any PyPI token it contained."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "yarnrc",
|
|
29
|
+
re: /(^|\/)\.yarnrc(\.yml)?$/iu,
|
|
30
|
+
category: "credential-file",
|
|
31
|
+
severity: 4,
|
|
32
|
+
title: "Yarn registry configuration bundled in publish payload",
|
|
33
|
+
recommendation: "Exclude Yarn registry config and verify it holds no credentials."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "netrc",
|
|
37
|
+
re: /(^|\/)_?\.?netrc$/iu,
|
|
38
|
+
category: "credential-file",
|
|
39
|
+
severity: 5,
|
|
40
|
+
title: ".netrc bundled in publish payload",
|
|
41
|
+
recommendation: "Remove .netrc and rotate the machine credentials it stored."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "git-credentials",
|
|
45
|
+
re: /(^|\/)\.git-credentials$/iu,
|
|
46
|
+
category: "credential-file",
|
|
47
|
+
severity: 5,
|
|
48
|
+
title: ".git-credentials bundled in publish payload",
|
|
49
|
+
recommendation: "Remove the file and rotate the git access token it stored."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "aws-credentials",
|
|
53
|
+
re: /(^|\/)\.aws\/(credentials|config)$/iu,
|
|
54
|
+
category: "credential-file",
|
|
55
|
+
severity: 5,
|
|
56
|
+
title: "AWS credentials bundled in publish payload",
|
|
57
|
+
recommendation: "Remove the credentials file and rotate the access key."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "gcloud-sa",
|
|
61
|
+
re: /(application_default_credentials|service[_-]?account[^/]*)\.json$/iu,
|
|
62
|
+
gateContent: /"type"\s*:\s*"service_account"|"private_key"/u,
|
|
63
|
+
category: "credential-file",
|
|
64
|
+
severity: 5,
|
|
65
|
+
title: "Google service-account key bundled in publish payload",
|
|
66
|
+
recommendation: "Remove the key file and rotate the service account."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "kube-config",
|
|
70
|
+
re: /(^|\/)(\.kube\/config|kubeconfig)$/iu,
|
|
71
|
+
gateContent: /client-key-data:|token:/u,
|
|
72
|
+
category: "credential-file",
|
|
73
|
+
severity: 5,
|
|
74
|
+
title: "Kubernetes config bundled in publish payload",
|
|
75
|
+
recommendation: "Remove the kubeconfig and rotate the cluster credentials."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "docker-config",
|
|
79
|
+
re: /(^|\/)\.docker\/config\.json$/iu,
|
|
80
|
+
gateContent: /"auths"/u,
|
|
81
|
+
category: "credential-file",
|
|
82
|
+
severity: 5,
|
|
83
|
+
title: "Docker registry credentials bundled in publish payload",
|
|
84
|
+
recommendation: "Remove the file and rotate the registry credentials."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "cargo-credentials",
|
|
88
|
+
re: /(^|\/)\.cargo\/credentials(\.toml)?$/iu,
|
|
89
|
+
category: "credential-file",
|
|
90
|
+
severity: 5,
|
|
91
|
+
title: "Cargo registry credentials bundled in publish payload",
|
|
92
|
+
recommendation: "Remove the file and revoke the crates.io token."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "htpasswd",
|
|
96
|
+
re: /(^|\/)\.htpasswd$/iu,
|
|
97
|
+
category: "credential-file",
|
|
98
|
+
severity: 4,
|
|
99
|
+
title: ".htpasswd bundled in publish payload",
|
|
100
|
+
recommendation: "Remove the file; the password hashes are a cracking target."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "ssh-key",
|
|
104
|
+
re: /(^|\/)id_(rsa|ed25519|ecdsa|dsa)$/iu,
|
|
105
|
+
category: "private-key",
|
|
106
|
+
severity: 5,
|
|
107
|
+
title: "SSH private key bundled in publish payload",
|
|
108
|
+
recommendation: "Remove the key file and rotate the key."
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "ssh-pubkey",
|
|
112
|
+
re: /(^|\/)id_(rsa|ed25519|ecdsa|dsa)\.pub$/iu,
|
|
113
|
+
category: "credential-file",
|
|
114
|
+
severity: 2,
|
|
115
|
+
title: "SSH public key bundled in publish payload",
|
|
116
|
+
recommendation: "Public keys are not secret, but were likely included by mistake."
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "key-bundle",
|
|
120
|
+
re: /\.(p12|pfx|keystore|jks)$/iu,
|
|
121
|
+
category: "private-key",
|
|
122
|
+
severity: 5,
|
|
123
|
+
title: "Key/certificate bundle in publish payload",
|
|
124
|
+
recommendation: "Remove the keystore and rotate any private key it holds."
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: "har-file",
|
|
128
|
+
re: /\.har$/iu,
|
|
129
|
+
category: "credential-file",
|
|
130
|
+
severity: 4,
|
|
131
|
+
title: "HTTP archive (.har) bundled in publish payload",
|
|
132
|
+
recommendation: "HAR files routinely contain Authorization headers and cookies — remove it."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "git-dir",
|
|
136
|
+
re: /(^|\/)\.git\//iu,
|
|
137
|
+
category: "scm-leakage",
|
|
138
|
+
severity: 4,
|
|
139
|
+
title: "Git history bundled in publish payload",
|
|
140
|
+
recommendation: "Exclude .git — full history (including deleted secrets) is recoverable."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: "vcs-other",
|
|
144
|
+
re: /(^|\/)\.(svn|hg|bzr)\//iu,
|
|
145
|
+
category: "scm-leakage",
|
|
146
|
+
severity: 3,
|
|
147
|
+
title: "Version-control metadata bundled in publish payload",
|
|
148
|
+
recommendation: "Exclude version-control directories from the package."
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "tfstate",
|
|
152
|
+
re: /\.tfstate(\.backup)?$/iu,
|
|
153
|
+
category: "iac-secret",
|
|
154
|
+
severity: 5,
|
|
155
|
+
title: "Terraform state bundled in publish payload",
|
|
156
|
+
recommendation: "Remove it — tfstate stores resource secrets (passwords, keys) in plaintext."
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: "terraform-dir",
|
|
160
|
+
re: /(^|\/)\.terraform\//iu,
|
|
161
|
+
category: "iac-secret",
|
|
162
|
+
severity: 3,
|
|
163
|
+
title: "Terraform working directory bundled in publish payload",
|
|
164
|
+
recommendation: "Exclude .terraform from the package."
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "ci-config",
|
|
168
|
+
re: /(^|\/)(\.github\/workflows\/[^/]+\.ya?ml|\.gitlab-ci\.yml|\.circleci\/config\.yml|Jenkinsfile|azure-pipelines\.yml|\.travis\.yml|bitbucket-pipelines\.yml|\.drone\.yml)$/iu,
|
|
169
|
+
category: "ci-config",
|
|
170
|
+
severity: 3,
|
|
171
|
+
title: "CI configuration bundled in publish payload",
|
|
172
|
+
recommendation: "CI configs are rarely meant to ship and can carry inline tokens — exclude them."
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "source-map",
|
|
176
|
+
re: /\.(js|mjs|cjs|css)\.map$/iu,
|
|
177
|
+
category: "source-map",
|
|
178
|
+
severity: 3,
|
|
179
|
+
title: "Source map bundled in publish payload",
|
|
180
|
+
recommendation: "Source maps can reconstruct your original source — exclude them unless intended."
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: "node-modules",
|
|
184
|
+
re: /(^|\/)node_modules\//iu,
|
|
185
|
+
category: "build-artifact",
|
|
186
|
+
severity: 2,
|
|
187
|
+
title: "node_modules bundled in publish payload",
|
|
188
|
+
recommendation: "Exclude node_modules unless declared in bundledDependencies."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "pycache",
|
|
192
|
+
re: /(^|\/)(__pycache__\/|[^/]+\.py[co])$/iu,
|
|
193
|
+
category: "build-artifact",
|
|
194
|
+
severity: 1,
|
|
195
|
+
title: "Python bytecode bundled in publish payload",
|
|
196
|
+
recommendation: "Exclude __pycache__ and compiled bytecode."
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: "coverage",
|
|
200
|
+
re: /(^|\/)(coverage|\.nyc_output)\/|\.lcov$/iu,
|
|
201
|
+
category: "build-artifact",
|
|
202
|
+
severity: 2,
|
|
203
|
+
title: "Coverage output bundled in publish payload",
|
|
204
|
+
recommendation: "Exclude coverage reports — they leak local paths and test internals."
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
id: "memory-dump",
|
|
208
|
+
re: /\.(heapsnapshot|cpuprofile|dmp)$|(^|\/)core(\.[0-9]+)?$/iu,
|
|
209
|
+
category: "build-artifact",
|
|
210
|
+
severity: 4,
|
|
211
|
+
title: "Memory/heap dump bundled in publish payload",
|
|
212
|
+
recommendation: "Remove it — dumps can contain live secrets from process memory."
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: "log-file",
|
|
216
|
+
re: /(^|\/)(npm-debug\.log|yarn-error\.log|\.pnpm-debug\.log)$|\.log$/iu,
|
|
217
|
+
category: "build-artifact",
|
|
218
|
+
severity: 2,
|
|
219
|
+
title: "Log file bundled in publish payload",
|
|
220
|
+
recommendation: "Exclude logs — they often contain tokens and environment dumps."
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: "ds-store",
|
|
224
|
+
re: /(^|\/)\.DS_Store$/iu,
|
|
225
|
+
category: "editor-os-junk",
|
|
226
|
+
severity: 2,
|
|
227
|
+
title: ".DS_Store bundled in publish payload",
|
|
228
|
+
recommendation: "Exclude .DS_Store — it leaks the full directory listing."
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: "os-junk",
|
|
232
|
+
re: /(^|\/)(Thumbs\.db|desktop\.ini)$/iu,
|
|
233
|
+
category: "editor-os-junk",
|
|
234
|
+
severity: 1,
|
|
235
|
+
title: "OS metadata bundled in publish payload",
|
|
236
|
+
recommendation: "Exclude OS metadata files."
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "editor-dir",
|
|
240
|
+
re: /(^|\/)\.(vscode|idea)\//iu,
|
|
241
|
+
category: "editor-os-junk",
|
|
242
|
+
severity: 2,
|
|
243
|
+
title: "Editor configuration bundled in publish payload",
|
|
244
|
+
recommendation: "Exclude editor dirs — .idea can hold data-source passwords."
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: "editor-swap",
|
|
248
|
+
re: /(\.sw[op]|~|\.bak|\.orig)$/iu,
|
|
249
|
+
category: "editor-os-junk",
|
|
250
|
+
severity: 2,
|
|
251
|
+
title: "Editor/backup file bundled in publish payload",
|
|
252
|
+
recommendation: "Exclude swap/backup files — they can hold unsaved secret edits."
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: "sql-dump",
|
|
256
|
+
re: /\.(sql|sql\.gz|dump)$/iu,
|
|
257
|
+
category: "data-dump",
|
|
258
|
+
severity: 3,
|
|
259
|
+
title: "Database dump bundled in publish payload",
|
|
260
|
+
recommendation: "Exclude DB dumps — they may contain PII and credentials."
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
id: "sqlite-db",
|
|
264
|
+
re: /\.(sqlite|sqlite3|db|rdb)$/iu,
|
|
265
|
+
category: "data-dump",
|
|
266
|
+
severity: 3,
|
|
267
|
+
title: "Database file bundled in publish payload",
|
|
268
|
+
recommendation: "Exclude database files — they may contain live sessions and tokens."
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "pcap",
|
|
272
|
+
re: /\.pcap(ng)?$/iu,
|
|
273
|
+
category: "data-dump",
|
|
274
|
+
severity: 4,
|
|
275
|
+
title: "Network capture bundled in publish payload",
|
|
276
|
+
recommendation: "Remove it — captures expose auth headers and cookies in cleartext."
|
|
277
|
+
}
|
|
278
|
+
];
|
|
279
|
+
export const CONTENT_RULES = [
|
|
280
|
+
{
|
|
281
|
+
id: "pem-private-key",
|
|
282
|
+
re: /-----BEGIN ((?:OPENSSH |RSA |DSA |EC |ENCRYPTED |PGP )?PRIVATE KEY)-----/u,
|
|
283
|
+
category: "private-key",
|
|
284
|
+
severity: 5,
|
|
285
|
+
title: "Private-key block embedded in a published file",
|
|
286
|
+
recommendation: "Treat the key as compromised, rotate it, and remove the file."
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: "age-secret-key",
|
|
290
|
+
re: /AGE-SECRET-KEY-1[0-9A-Z]{50,}/u,
|
|
291
|
+
category: "private-key",
|
|
292
|
+
severity: 5,
|
|
293
|
+
title: "age secret key embedded in a published file",
|
|
294
|
+
recommendation: "Rotate the age key and remove it from the payload."
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: "aws-secret-key",
|
|
298
|
+
re: /aws_secret_access_key\s*=\s*[A-Za-z0-9/+]{40}/iu,
|
|
299
|
+
category: "bundled-secret",
|
|
300
|
+
severity: 5,
|
|
301
|
+
title: "AWS secret access key embedded in a published file",
|
|
302
|
+
recommendation: "Rotate the AWS access key and remove the secret."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
id: "aws-access-key-id",
|
|
306
|
+
re: /\b(?:AKIA|ASIA|AROA|AGPA)[0-9A-Z]{16}\b/u,
|
|
307
|
+
category: "bundled-secret",
|
|
308
|
+
severity: 4,
|
|
309
|
+
title: "AWS access key ID embedded in a published file",
|
|
310
|
+
recommendation: "Rotate the AWS access key and remove the credential."
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: "github-token",
|
|
314
|
+
re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36}\b|\bgithub_pat_[A-Za-z0-9_]{82}\b/u,
|
|
315
|
+
category: "bundled-secret",
|
|
316
|
+
severity: 5,
|
|
317
|
+
title: "GitHub token embedded in a published file",
|
|
318
|
+
recommendation: "Revoke the token and remove it from the payload."
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
id: "gitlab-token",
|
|
322
|
+
re: /\b(?:glpat|gldt|glrt|glsoat)-[A-Za-z0-9_-]{20,}\b/u,
|
|
323
|
+
category: "bundled-secret",
|
|
324
|
+
severity: 5,
|
|
325
|
+
title: "GitLab token embedded in a published file",
|
|
326
|
+
recommendation: "Revoke the GitLab token and remove it from the payload."
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
id: "slack-token",
|
|
330
|
+
re: /\bxox[abpr]-[0-9]+-[0-9]+(?:-[0-9]+)?-[A-Za-z0-9]{10,}\b/u,
|
|
331
|
+
category: "bundled-secret",
|
|
332
|
+
severity: 5,
|
|
333
|
+
title: "Slack token embedded in a published file",
|
|
334
|
+
recommendation: "Revoke the Slack token and remove it from the payload."
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
id: "slack-webhook",
|
|
338
|
+
re: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9]+\/B[A-Za-z0-9]+\/[A-Za-z0-9]+/u,
|
|
339
|
+
category: "bundled-secret",
|
|
340
|
+
severity: 3,
|
|
341
|
+
title: "Slack webhook URL embedded in a published file",
|
|
342
|
+
recommendation: "Rotate the webhook and remove the URL from the payload."
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
id: "stripe-key",
|
|
346
|
+
re: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\b/u,
|
|
347
|
+
category: "bundled-secret",
|
|
348
|
+
severity: 5,
|
|
349
|
+
title: "Stripe API key embedded in a published file",
|
|
350
|
+
recommendation: "Roll the Stripe key and remove it from the payload."
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
id: "google-api-key",
|
|
354
|
+
re: /\bAIza[0-9A-Za-z_-]{35}\b/u,
|
|
355
|
+
category: "bundled-secret",
|
|
356
|
+
severity: 4,
|
|
357
|
+
title: "Google API key embedded in a published file",
|
|
358
|
+
recommendation: "Rotate the Google API key and remove it from the payload."
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
id: "sendgrid-key",
|
|
362
|
+
re: /\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/u,
|
|
363
|
+
category: "bundled-secret",
|
|
364
|
+
severity: 5,
|
|
365
|
+
title: "SendGrid API key embedded in a published file",
|
|
366
|
+
recommendation: "Revoke the SendGrid key and remove it from the payload."
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: "twilio-key",
|
|
370
|
+
re: /\bSK[0-9a-fA-F]{32}\b/u,
|
|
371
|
+
category: "bundled-secret",
|
|
372
|
+
severity: 4,
|
|
373
|
+
title: "Twilio API key embedded in a published file",
|
|
374
|
+
recommendation: "Rotate the Twilio key and remove it from the payload."
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
id: "npm-auth-token",
|
|
378
|
+
re: /_authToken\s*=\s*[A-Za-z0-9_=+/-]{20,}|\bNODE_AUTH_TOKEN\s*=\s*[A-Za-z0-9_=+/-]{20,}|\bnpm_[A-Za-z0-9]{36}\b/u,
|
|
379
|
+
category: "bundled-secret",
|
|
380
|
+
severity: 4,
|
|
381
|
+
title: "npm registry token embedded in a published file",
|
|
382
|
+
recommendation: "Revoke the registry token and exclude the file."
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
id: "db-connection-string",
|
|
386
|
+
re: /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp):\/\/[^:@\s/]+:[^@\s/]+@[^/\s]+/u,
|
|
387
|
+
allow: /:\/\/[^:@/]+:(password|pass|user|example|changeme|xxx+|\*+)@|@(localhost|127\.0\.0\.1|example\.|host)/iu,
|
|
388
|
+
category: "bundled-secret",
|
|
389
|
+
severity: 4,
|
|
390
|
+
title: "Database connection string with password embedded in a published file",
|
|
391
|
+
recommendation: "Move the credential to configuration and remove it from the payload."
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
id: "jwt",
|
|
395
|
+
re: /\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/u,
|
|
396
|
+
category: "bundled-secret",
|
|
397
|
+
severity: 3,
|
|
398
|
+
title: "JWT embedded in a published file",
|
|
399
|
+
recommendation: "Confirm the token is not a live credential, then remove it."
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
id: "ansible-vault",
|
|
403
|
+
re: /\$ANSIBLE_VAULT;[0-9.]+;AES256/u,
|
|
404
|
+
category: "iac-secret",
|
|
405
|
+
severity: 3,
|
|
406
|
+
title: "Ansible Vault ciphertext embedded in a published file",
|
|
407
|
+
recommendation: "Exclude vault files; ensure the vault password is not shipped alongside."
|
|
408
|
+
}
|
|
409
|
+
];
|
|
410
|
+
export const RISKY_SCRIPT_NAMES = [
|
|
411
|
+
"preinstall",
|
|
412
|
+
"install",
|
|
413
|
+
"postinstall",
|
|
414
|
+
"preprepare",
|
|
415
|
+
"prepare",
|
|
416
|
+
"postprepare",
|
|
417
|
+
"prepublish",
|
|
418
|
+
"prepublishOnly",
|
|
419
|
+
"prepack",
|
|
420
|
+
"postpack",
|
|
421
|
+
"preuninstall",
|
|
422
|
+
"uninstall"
|
|
423
|
+
];
|
|
424
|
+
export const DANGEROUS_SCRIPT_RE = /\|\s*(?:sh|bash|zsh)\b|\beval\s|node\s+-e\b|python[0-9.]*\s+-c\b|base64\s+-d|(?:curl|wget|fetch)\b[^\n]*\|\s*\w*sh\b/iu;
|
|
425
|
+
export const INVISIBLE_UNICODE_RE = /[\u200B-\u200F\u2060-\u2064\u202A-\u202E\u2066-\u2069\uFEFF]/u;
|
|
426
|
+
export const BIDI_OVERRIDE_RE = /[\u202A-\u202E\u2066-\u2069]/u;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { Box, useApp } from "ink";
|
|
4
|
+
import { combineAction, auditExitCode, displayTarget } from "../commands/audit.js";
|
|
5
|
+
import { AuditResultsView } from "./components/AuditResultsView.js";
|
|
6
|
+
export const AuditApp = ({ gathered, initialDeep, deepPromise, onExitCode }) => {
|
|
7
|
+
const { exit } = useApp();
|
|
8
|
+
const [deep, setDeep] = useState(initialDeep);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!deepPromise)
|
|
11
|
+
return;
|
|
12
|
+
let live = true;
|
|
13
|
+
deepPromise
|
|
14
|
+
.then((result) => { if (live)
|
|
15
|
+
setDeep(result); })
|
|
16
|
+
.catch((error) => {
|
|
17
|
+
if (live)
|
|
18
|
+
setDeep({ ran: false, reason: error instanceof Error ? error.message : "deep audit failed" });
|
|
19
|
+
});
|
|
20
|
+
return () => { live = false; };
|
|
21
|
+
}, [deepPromise]);
|
|
22
|
+
const { parsed, scope, localAction, findings, publishSetSource, fileCount } = gathered;
|
|
23
|
+
const policy = { requireDeep: parsed.requireDeep, failOn: parsed.failOn };
|
|
24
|
+
const resolvedDeep = deep ?? { ran: false, reason: "deep audit required but unavailable" };
|
|
25
|
+
const exitCode = auditExitCode(localAction, resolvedDeep, policy);
|
|
26
|
+
const combined = combineAction(localAction, resolvedDeep);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
process.exitCode = exitCode;
|
|
29
|
+
onExitCode?.(exitCode);
|
|
30
|
+
}, [exitCode, onExitCode]);
|
|
31
|
+
const handleExit = useCallback(() => {
|
|
32
|
+
const finalDeep = deep ?? { ran: false, reason: "deep audit required but unavailable" };
|
|
33
|
+
const code = auditExitCode(localAction, finalDeep, policy);
|
|
34
|
+
process.exitCode = code;
|
|
35
|
+
onExitCode?.(code);
|
|
36
|
+
exit();
|
|
37
|
+
}, [deep, localAction, policy, onExitCode, exit]);
|
|
38
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsx(AuditResultsView, { findings: findings, action: combined, artifact: scope.artifact, ecosystem: scope.ecosystem, target: displayTarget(scope.root), fileCount: fileCount, publishSetSource: publishSetSource, deep: deep, onExit: handleExit }) }));
|
|
39
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { renderLogo } from "../../scan-ui/logo.js";
|
|
5
|
+
import { useTerminalSize } from "../../scan-ui/hooks/useTerminalSize.js";
|
|
6
|
+
import { verdictGlyph } from "../format.js";
|
|
7
|
+
const ACTION_COLOR = {
|
|
8
|
+
block: "red",
|
|
9
|
+
warn: "yellow",
|
|
10
|
+
pass: "green"
|
|
11
|
+
};
|
|
12
|
+
const ACTION_PAINT = {
|
|
13
|
+
block: chalk.red.bold,
|
|
14
|
+
warn: chalk.yellow.bold,
|
|
15
|
+
pass: chalk.green.bold
|
|
16
|
+
};
|
|
17
|
+
export const AuditHeader = ({ action, artifact, ecosystem, countSummary, fileCount, fallback }) => {
|
|
18
|
+
const logo = renderLogo(action);
|
|
19
|
+
const { cols } = useTerminalSize();
|
|
20
|
+
const showLogo = cols >= 60;
|
|
21
|
+
const fileLabel = `${fileCount} file${fileCount === 1 ? "" : "s"}`;
|
|
22
|
+
const paint = ACTION_PAINT[action];
|
|
23
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor: ACTION_COLOR[action], paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsxs(Box, { flexDirection: "row", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { children: [paint(`${verdictGlyph(action)} ${action.toUpperCase()}`), " ", chalk.bold(artifact), " ", chalk.dim(`· ${ecosystem}`)] }), _jsx(Text, { children: chalk.dim(`${countSummary} in ${fileLabel}`) }), fallback && _jsx(Text, { children: chalk.dim("publish set approximated") })] }), showLogo && (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: logo.map((line, i) => _jsx(Text, { children: line }, i)) }))] }) }));
|
|
24
|
+
};
|