fivosense 0.1.5 → 0.2.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/.kilo/skill/fivosense/skill.json +5 -5
- package/COMPLETE_SUMMARY.md +412 -0
- package/DEPLOYMENT_GUIDE.md +2 -2
- package/FINAL_VERIFICATION.md +316 -0
- package/GITHUB_PUSH.md +4 -4
- package/LICENSE +1 -1
- package/README.md +290 -208
- package/RELEASE_READY.md +3 -3
- package/bin/fivosense.mjs +6 -0
- package/dist/ai/client.d.ts +33 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +170 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/judge.d.ts +9 -3
- package/dist/ai/judge.d.ts.map +1 -1
- package/dist/ai/judge.js +49 -14
- package/dist/ai/judge.js.map +1 -1
- package/dist/cli/index.d.ts +3 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +6 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/core/orchestrator.d.ts +34 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +211 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/scope.d.ts +32 -0
- package/dist/core/scope.d.ts.map +1 -0
- package/dist/core/scope.js +149 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/editors/vscode.d.ts +4 -2
- package/dist/editors/vscode.d.ts.map +1 -1
- package/dist/editors/vscode.js +6 -0
- package/dist/editors/vscode.js.map +1 -1
- package/dist/engine/adversary.d.ts +9 -2
- package/dist/engine/adversary.d.ts.map +1 -1
- package/dist/engine/adversary.js +47 -13
- package/dist/engine/adversary.js.map +1 -1
- package/dist/engine/graph.d.ts +4 -1
- package/dist/engine/graph.d.ts.map +1 -1
- package/dist/engine/graph.js +6 -0
- package/dist/engine/graph.js.map +1 -1
- package/dist/engine/poc.d.ts +26 -0
- package/dist/engine/poc.d.ts.map +1 -0
- package/dist/engine/poc.js +179 -0
- package/dist/engine/poc.js.map +1 -0
- package/dist/engine/reach.d.ts +4 -2
- package/dist/engine/reach.d.ts.map +1 -1
- package/dist/engine/reach.js +6 -0
- package/dist/engine/reach.js.map +1 -1
- package/dist/engine/sinks.d.ts +22 -32
- package/dist/engine/sinks.d.ts.map +1 -1
- package/dist/engine/sinks.js +338 -44
- package/dist/engine/sinks.js.map +1 -1
- package/dist/engine/sources.d.ts +11 -19
- package/dist/engine/sources.d.ts.map +1 -1
- package/dist/engine/sources.js +100 -24
- package/dist/engine/sources.js.map +1 -1
- package/dist/engine/taint.d.ts +6 -0
- package/dist/engine/taint.d.ts.map +1 -1
- package/dist/engine/taint.js +6 -0
- package/dist/engine/taint.js.map +1 -1
- package/dist/engine/verify.d.ts +4 -1
- package/dist/engine/verify.d.ts.map +1 -1
- package/dist/engine/verify.js +6 -0
- package/dist/engine/verify.js.map +1 -1
- package/dist/features/badge.d.ts +6 -0
- package/dist/features/badge.d.ts.map +1 -1
- package/dist/features/badge.js +4 -1
- package/dist/features/badge.js.map +1 -1
- package/dist/features/fix.d.ts +6 -0
- package/dist/features/fix.d.ts.map +1 -1
- package/dist/features/fix.js +4 -1
- package/dist/features/fix.js.map +1 -1
- package/dist/features/index.d.ts +6 -0
- package/dist/features/index.d.ts.map +1 -1
- package/dist/features/index.js +6 -0
- package/dist/features/index.js.map +1 -1
- package/dist/features/roast.d.ts +6 -0
- package/dist/features/roast.d.ts.map +1 -1
- package/dist/features/roast.js +4 -1
- package/dist/features/roast.js.map +1 -1
- package/dist/hooks/agent.d.ts +4 -1
- package/dist/hooks/agent.d.ts.map +1 -1
- package/dist/hooks/agent.js +6 -0
- package/dist/hooks/agent.js.map +1 -1
- package/dist/hooks/git.d.ts +34 -0
- package/dist/hooks/git.d.ts.map +1 -0
- package/dist/hooks/git.js +161 -0
- package/dist/hooks/git.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/rules/destructive.d.ts +12 -21
- package/dist/rules/destructive.d.ts.map +1 -1
- package/dist/rules/destructive.js +306 -24
- package/dist/rules/destructive.js.map +1 -1
- package/dist/rules/secrets.d.ts +8 -10
- package/dist/rules/secrets.d.ts.map +1 -1
- package/dist/rules/secrets.js +294 -17
- package/dist/rules/secrets.js.map +1 -1
- package/mcp/index.js +55 -20
- package/mcp/package-lock.json +382 -0
- package/mcp/package.json +21 -4
- package/package.json +5 -5
- package/src/ai/client.ts +226 -0
- package/src/ai/judge.ts +58 -14
- package/src/cli/index.ts +7 -1
- package/src/core/orchestrator.ts +266 -0
- package/src/core/scope.ts +175 -0
- package/src/editors/vscode.ts +7 -0
- package/src/engine/adversary.ts +55 -12
- package/src/engine/graph.ts +7 -0
- package/src/engine/poc.ts +219 -0
- package/src/engine/reach.ts +7 -0
- package/src/engine/sinks.ts +358 -45
- package/src/engine/sources.ts +109 -24
- package/src/engine/taint.ts +7 -0
- package/src/engine/verify.ts +7 -0
- package/src/features/badge.ts +7 -0
- package/src/features/fix.ts +7 -0
- package/src/features/index.ts +7 -0
- package/src/features/roast.ts +7 -0
- package/src/hooks/agent.ts +7 -0
- package/src/hooks/git.ts +194 -0
- package/src/index.ts +7 -0
- package/src/rules/destructive.ts +316 -26
- package/src/rules/secrets.ts +306 -17
- package/vscode-extension/CHANGELOG.md +14 -2
- package/vscode-extension/LICENSE +1 -1
- package/vscode-extension/README.md +28 -23
- package/vscode-extension/fivosense-vscode-0.1.0.vsix +0 -0
- package/vscode-extension/fivosense-vscode-0.1.1.vsix +0 -0
- package/vscode-extension/package-lock.json +6 -6
- package/vscode-extension/package.json +7 -5
- package/vscode-extension/src/extension.ts +65 -11
package/src/rules/secrets.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* FivoSense - AI Security Scanner
|
|
3
|
+
* Copyright (c) 2026 thevinsoni
|
|
4
|
+
* Licensed under the MIT License
|
|
5
|
+
* https://github.com/thevinsoni/sense
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Secret detection — finds hardcoded API keys, tokens, passwords
|
|
10
|
+
* 55+ patterns covering AI, cloud, SaaS, payments, databases, and dev tools
|
|
3
11
|
*/
|
|
4
12
|
|
|
5
13
|
export interface SecretPattern {
|
|
@@ -9,46 +17,298 @@ export interface SecretPattern {
|
|
|
9
17
|
severity: 'high' | 'medium';
|
|
10
18
|
}
|
|
11
19
|
|
|
12
|
-
/**
|
|
13
|
-
* Common secret patterns
|
|
14
|
-
*/
|
|
15
20
|
export const SECRET_PATTERNS: SecretPattern[] = [
|
|
21
|
+
// === AI / ML ===
|
|
16
22
|
{
|
|
17
|
-
pattern: /['"][A-Za-z0-9_]{
|
|
18
|
-
type: '
|
|
19
|
-
description: '
|
|
23
|
+
pattern: /['"]sk-proj-[A-Za-z0-9_-]{20,}['"]/,
|
|
24
|
+
type: 'openai_project_key',
|
|
25
|
+
description: 'OpenAI Project API key',
|
|
20
26
|
severity: 'high',
|
|
21
27
|
},
|
|
22
28
|
{
|
|
23
|
-
pattern: /['"]sk-[A-Za-z0-9]{
|
|
29
|
+
pattern: /['"]sk-[A-Za-z0-9]{20,}['"]/,
|
|
24
30
|
type: 'openai_key',
|
|
25
31
|
description: 'OpenAI API key',
|
|
26
32
|
severity: 'high',
|
|
27
33
|
},
|
|
34
|
+
{
|
|
35
|
+
pattern: /['"]sk-ant-[A-Za-z0-9_-]{20,}['"]/,
|
|
36
|
+
type: 'anthropic_key',
|
|
37
|
+
description: 'Anthropic Claude API key',
|
|
38
|
+
severity: 'high',
|
|
39
|
+
},
|
|
28
40
|
{
|
|
29
41
|
pattern: /['"]AIza[A-Za-z0-9_-]{35}['"]/,
|
|
30
42
|
type: 'google_api_key',
|
|
31
43
|
description: 'Google API key',
|
|
32
44
|
severity: 'high',
|
|
33
45
|
},
|
|
46
|
+
{
|
|
47
|
+
pattern: /['"]ya29\.[A-Za-z0-9_-]+['"]/,
|
|
48
|
+
type: 'google_oauth_token',
|
|
49
|
+
description: 'Google OAuth access token',
|
|
50
|
+
severity: 'high',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
pattern: /['"][0-9]+-[A-Za-z0-9_]{32}\.apps\.googleusercontent\.com['"]/,
|
|
54
|
+
type: 'google_oauth_client_id',
|
|
55
|
+
description: 'Google OAuth client ID',
|
|
56
|
+
severity: 'high',
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// === Cloud Providers ===
|
|
34
60
|
{
|
|
35
61
|
pattern: /['"]AKIA[A-Z0-9]{16}['"]/,
|
|
36
62
|
type: 'aws_access_key',
|
|
37
63
|
description: 'AWS Access Key ID',
|
|
38
64
|
severity: 'high',
|
|
39
65
|
},
|
|
66
|
+
{
|
|
67
|
+
pattern: /['"]ASIA[A-Z0-9]{16}['"]/,
|
|
68
|
+
type: 'aws_temp_key',
|
|
69
|
+
description: 'AWS Temporary Access Key',
|
|
70
|
+
severity: 'high',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
pattern: /aws[_-]?secret[_-]?access[_-]?key\s*[:=]\s*['"][A-Za-z0-9/+=]{40}['"]/i,
|
|
74
|
+
type: 'aws_secret_key',
|
|
75
|
+
description: 'AWS Secret Access Key',
|
|
76
|
+
severity: 'high',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
pattern: /['"]arn:aws:[a-z0-9-]+:[a-z0-9-]*:[0-9]+:/,
|
|
80
|
+
type: 'aws_arn',
|
|
81
|
+
description: 'AWS ARN (resource identifier)',
|
|
82
|
+
severity: 'medium',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
pattern: /AccountKey\s*=\s*[A-Za-z0-9+/=]{80,}/i,
|
|
86
|
+
type: 'azure_storage_key',
|
|
87
|
+
description: 'Azure Storage Account Key',
|
|
88
|
+
severity: 'high',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
pattern: /['"][a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}['"]/,
|
|
92
|
+
type: 'azure_tenant_or_client',
|
|
93
|
+
description: 'Azure Tenant/Client UUID',
|
|
94
|
+
severity: 'medium',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
pattern: /['"](?:AAAA)[A-Za-z0-9+/=]{40,}['"]/,
|
|
98
|
+
type: 'firebase_token',
|
|
99
|
+
description: 'Firebase authentication token',
|
|
100
|
+
severity: 'high',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
pattern: /['"]SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}['"]/,
|
|
104
|
+
type: 'sendgrid_key',
|
|
105
|
+
description: 'SendGrid API key',
|
|
106
|
+
severity: 'high',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
pattern: /['"]service_account['"]\s*[:=]/i,
|
|
110
|
+
type: 'gcp_service_account',
|
|
111
|
+
description: 'GCP service account',
|
|
112
|
+
severity: 'high',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
pattern: /['"]type['"]\s*[:=]\s*['"]service_account['"]/i,
|
|
116
|
+
type: 'gcp_sa_json',
|
|
117
|
+
description: 'GCP service account JSON',
|
|
118
|
+
severity: 'high',
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// === GitHub / Git ===
|
|
40
122
|
{
|
|
41
123
|
pattern: /['"]ghp_[A-Za-z0-9]{36}['"]/,
|
|
42
|
-
type: '
|
|
43
|
-
description: 'GitHub Personal Access Token',
|
|
124
|
+
type: 'github_pat',
|
|
125
|
+
description: 'GitHub Personal Access Token (classic)',
|
|
126
|
+
severity: 'high',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
pattern: /['"]github_pat_[A-Za-z0-9_]{22,}['"]/,
|
|
130
|
+
type: 'github_fine_grained_pat',
|
|
131
|
+
description: 'GitHub Fine-Grained PAT',
|
|
132
|
+
severity: 'high',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
pattern: /['"]gho_[A-Za-z0-9]{36}['"]/,
|
|
136
|
+
type: 'github_oauth',
|
|
137
|
+
description: 'GitHub OAuth token',
|
|
44
138
|
severity: 'high',
|
|
45
139
|
},
|
|
140
|
+
{
|
|
141
|
+
pattern: /['"]ghs_[A-Za-z0-9]{36}['"]/,
|
|
142
|
+
type: 'github_app_token',
|
|
143
|
+
description: 'GitHub App installation token',
|
|
144
|
+
severity: 'high',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
pattern: /['"]ghr_[A-Za-z0-9]{36}['"]/,
|
|
148
|
+
type: 'github_refresh',
|
|
149
|
+
description: 'GitHub refresh token',
|
|
150
|
+
severity: 'high',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
pattern: /['"]glpat-[A-Za-z0-9_-]{20,}['"]/,
|
|
154
|
+
type: 'gitlab_pat',
|
|
155
|
+
description: 'GitLab Personal Access Token',
|
|
156
|
+
severity: 'high',
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// === Communication ===
|
|
46
160
|
{
|
|
47
161
|
pattern: /['"]xox[baprs]-[A-Za-z0-9-]{10,}['"]/,
|
|
48
162
|
type: 'slack_token',
|
|
49
163
|
description: 'Slack Token',
|
|
50
164
|
severity: 'high',
|
|
51
165
|
},
|
|
166
|
+
{
|
|
167
|
+
pattern: /['"]https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+['"]/,
|
|
168
|
+
type: 'slack_webhook',
|
|
169
|
+
description: 'Slack Webhook URL',
|
|
170
|
+
severity: 'high',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
pattern: /['"][0-9]+:AA[A-Za-z0-9_-]{30,}['"]/,
|
|
174
|
+
type: 'telegram_bot_token',
|
|
175
|
+
description: 'Telegram Bot Token',
|
|
176
|
+
severity: 'high',
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
pattern: /['"]discord(app)?\.com\/api\/webhooks\/[0-9]+\/[A-Za-z0-9_-]+['"]/,
|
|
180
|
+
type: 'discord_webhook',
|
|
181
|
+
description: 'Discord Webhook URL',
|
|
182
|
+
severity: 'high',
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
// === Payment ===
|
|
186
|
+
{
|
|
187
|
+
pattern: /['"]sk_live_[A-Za-z0-9]{20,}['"]/,
|
|
188
|
+
type: 'stripe_secret_live',
|
|
189
|
+
description: 'Stripe Secret Key (LIVE)',
|
|
190
|
+
severity: 'high',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
pattern: /['"]sk_test_[A-Za-z0-9]{20,}['"]/,
|
|
194
|
+
type: 'stripe_secret_test',
|
|
195
|
+
description: 'Stripe Secret Key (test)',
|
|
196
|
+
severity: 'high',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
pattern: /['"]rk_live_[A-Za-z0-9]{20,}['"]/,
|
|
200
|
+
type: 'stripe_restricted_live',
|
|
201
|
+
description: 'Stripe Restricted Key (LIVE)',
|
|
202
|
+
severity: 'high',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
pattern: /['"]rk_test_[A-Za-z0-9]{20,}['"]/,
|
|
206
|
+
type: 'stripe_restricted_test',
|
|
207
|
+
description: 'Stripe Restricted Key (test)',
|
|
208
|
+
severity: 'high',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
pattern: /['"]sq0csp-[A-Za-z0-9_-]{22,}['"]/,
|
|
212
|
+
type: 'square_key',
|
|
213
|
+
description: 'Square OAuth secret',
|
|
214
|
+
severity: 'high',
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
// === SaaS / Dev Tools ===
|
|
218
|
+
{
|
|
219
|
+
pattern: /['"]npm_[A-Za-z0-9]{36}['"]/,
|
|
220
|
+
type: 'npm_token',
|
|
221
|
+
description: 'npm access token',
|
|
222
|
+
severity: 'high',
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
pattern: /['"]pypi-[A-Za-z0-9_-]{50,}['"]/,
|
|
226
|
+
type: 'pypi_token',
|
|
227
|
+
description: 'PyPI API token',
|
|
228
|
+
severity: 'high',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
pattern: /['"]do_[a-zA-Z0-9]{64}['"]/,
|
|
232
|
+
type: 'digitalocean_token',
|
|
233
|
+
description: 'DigitalOcean API token',
|
|
234
|
+
severity: 'high',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
pattern: /['"]dop_v1_[a-f0-9]{64}['"]/,
|
|
238
|
+
type: 'doppler_token',
|
|
239
|
+
description: 'Doppler service token',
|
|
240
|
+
severity: 'high',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
pattern: /['"]NRAK-[A-Z0-9]{27}['"]/,
|
|
244
|
+
type: 'newrelic_key',
|
|
245
|
+
description: 'New Relic API key',
|
|
246
|
+
severity: 'high',
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
pattern: /['"]shpat_[a-fA-F0-9]{32}['"]/,
|
|
250
|
+
type: 'shopify_key',
|
|
251
|
+
description: 'Shopify Private App Access Token',
|
|
252
|
+
severity: 'high',
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
pattern: /['"]shpss_[a-fA-F0-9]{32}['"]/,
|
|
256
|
+
type: 'shopify_secret',
|
|
257
|
+
description: 'Shopify Shared Secret',
|
|
258
|
+
severity: 'high',
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
pattern: /['"]Bearer\s+[A-Za-z0-9_-]{20,}['"]/,
|
|
262
|
+
type: 'bearer_token',
|
|
263
|
+
description: 'Bearer authentication token',
|
|
264
|
+
severity: 'high',
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
pattern: /['"]Basic\s+[A-Za-z0-9+/=]{20,}['"]/,
|
|
268
|
+
type: 'basic_auth',
|
|
269
|
+
description: 'Basic authentication header',
|
|
270
|
+
severity: 'high',
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// === Database Connection Strings ===
|
|
274
|
+
{
|
|
275
|
+
pattern: /['"]mongodb(\+srv)?:\/\/[^'"]+['"]/,
|
|
276
|
+
type: 'mongodb_uri',
|
|
277
|
+
description: 'MongoDB connection string',
|
|
278
|
+
severity: 'high',
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
pattern: /['"]postgres(ql)?:\/\/[^'"]+['"]/,
|
|
282
|
+
type: 'postgres_uri',
|
|
283
|
+
description: 'PostgreSQL connection string',
|
|
284
|
+
severity: 'high',
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
pattern: /['"]mysql:\/\/[^'"]+['"]/,
|
|
288
|
+
type: 'mysql_uri',
|
|
289
|
+
description: 'MySQL connection string',
|
|
290
|
+
severity: 'high',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
pattern: /['"]redis:\/\/[^'"]+['"]/,
|
|
294
|
+
type: 'redis_uri',
|
|
295
|
+
description: 'Redis connection string',
|
|
296
|
+
severity: 'high',
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
pattern: /['"]amqps?:\/\/[^'"]+['"]/,
|
|
300
|
+
type: 'amqp_uri',
|
|
301
|
+
description: 'AMQP connection string',
|
|
302
|
+
severity: 'high',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
pattern: /['"]jdbc:[^'"]+['"]/,
|
|
306
|
+
type: 'jdbc_uri',
|
|
307
|
+
description: 'JDBC connection string',
|
|
308
|
+
severity: 'high',
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
// === Generic Hardcoded Credentials ===
|
|
52
312
|
{
|
|
53
313
|
pattern: /password\s*[:=]\s*['"][^'"]+['"]/i,
|
|
54
314
|
type: 'password',
|
|
@@ -67,6 +327,42 @@ export const SECRET_PATTERNS: SecretPattern[] = [
|
|
|
67
327
|
description: 'Hardcoded secret',
|
|
68
328
|
severity: 'high',
|
|
69
329
|
},
|
|
330
|
+
{
|
|
331
|
+
pattern: /token\s*[:=]\s*['"][^'"]{20,}['"]/i,
|
|
332
|
+
type: 'token',
|
|
333
|
+
description: 'Hardcoded token',
|
|
334
|
+
severity: 'high',
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
pattern: /private[_-]?key\s*[:=]\s*['"][^'"]+['"]/i,
|
|
338
|
+
type: 'private_key',
|
|
339
|
+
description: 'Hardcoded private key',
|
|
340
|
+
severity: 'high',
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
pattern: /access[_-]?key\s*[:=]\s*['"][^'"]+['"]/i,
|
|
344
|
+
type: 'access_key',
|
|
345
|
+
description: 'Hardcoded access key',
|
|
346
|
+
severity: 'high',
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
pattern: /auth[_-]?token\s*[:=]\s*['"][^'"]+['"]/i,
|
|
350
|
+
type: 'auth_token',
|
|
351
|
+
description: 'Hardcoded auth token',
|
|
352
|
+
severity: 'high',
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
pattern: /client[_-]?secret\s*[:=]\s*['"][^'"]+['"]/i,
|
|
356
|
+
type: 'client_secret',
|
|
357
|
+
description: 'Hardcoded client secret',
|
|
358
|
+
severity: 'high',
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
pattern: /['"][A-Za-z0-9_]{32,}['"]/,
|
|
362
|
+
type: 'generic_token',
|
|
363
|
+
description: 'Generic high-entropy token (32+ chars)',
|
|
364
|
+
severity: 'medium',
|
|
365
|
+
},
|
|
70
366
|
];
|
|
71
367
|
|
|
72
368
|
export interface SecretMatch {
|
|
@@ -77,15 +373,11 @@ export interface SecretMatch {
|
|
|
77
373
|
match: string;
|
|
78
374
|
}
|
|
79
375
|
|
|
80
|
-
/**
|
|
81
|
-
* Detect secrets in code
|
|
82
|
-
*/
|
|
83
376
|
export function detectSecrets(code: string): SecretMatch[] {
|
|
84
377
|
const lines = code.split('\n');
|
|
85
378
|
const matches: SecretMatch[] = [];
|
|
86
379
|
|
|
87
380
|
lines.forEach((line, index) => {
|
|
88
|
-
// Skip comments
|
|
89
381
|
if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
|
|
90
382
|
return;
|
|
91
383
|
}
|
|
@@ -107,9 +399,6 @@ export function detectSecrets(code: string): SecretMatch[] {
|
|
|
107
399
|
return matches;
|
|
108
400
|
}
|
|
109
401
|
|
|
110
|
-
/**
|
|
111
|
-
* Check if specific line contains a secret
|
|
112
|
-
*/
|
|
113
402
|
export function isSecretLine(line: string): SecretPattern | null {
|
|
114
403
|
for (const pattern of SECRET_PATTERNS) {
|
|
115
404
|
if (pattern.pattern.test(line)) {
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.1] - 2026-06-27
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Fixed vulnerability reporting structure (location.line instead of line)
|
|
7
|
+
- Fixed secret detection output
|
|
8
|
+
- Fixed destructive command reporting
|
|
9
|
+
- Updated to fivosense v0.1.6
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Separate handling for vulnerabilities, secrets, and destructive commands
|
|
13
|
+
- Improved taint-trace proof display
|
|
14
|
+
- Better error messages
|
|
15
|
+
|
|
3
16
|
## [0.1.0] - 2026-06-26
|
|
4
17
|
|
|
5
18
|
### Added
|
|
@@ -15,7 +28,6 @@
|
|
|
15
28
|
- Configurable severity levels
|
|
16
29
|
|
|
17
30
|
### Features
|
|
18
|
-
-
|
|
19
|
-
- Research-backed accuracy (F1 0.91-0.95)
|
|
31
|
+
- AST-based taint analysis
|
|
20
32
|
- Zero false negatives for critical vulnerabilities
|
|
21
33
|
- Detailed evidence with data-flow traces
|
package/vscode-extension/LICENSE
CHANGED
|
@@ -13,15 +13,18 @@ Real-time security vulnerability detection for JavaScript and TypeScript with AI
|
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
-
### From Marketplace
|
|
17
|
-
1. Open VS Code
|
|
18
|
-
2. Go to Extensions (Ctrl+Shift+X)
|
|
19
|
-
3. Search for "FivoSense"
|
|
20
|
-
4. Click Install
|
|
21
|
-
|
|
22
16
|
### From .vsix
|
|
23
17
|
```bash
|
|
24
|
-
code --install-extension fivosense-vscode-0.1.
|
|
18
|
+
code --install-extension fivosense-vscode-0.1.1.vsix
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### From Source
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/thevinsoni/sense.git
|
|
24
|
+
cd sense/vscode-extension
|
|
25
|
+
npm install
|
|
26
|
+
npm run package
|
|
27
|
+
code --install-extension fivosense-vscode-0.1.1.vsix
|
|
25
28
|
```
|
|
26
29
|
|
|
27
30
|
## Usage
|
|
@@ -80,14 +83,13 @@ const apiKey = process.env.OPENAI_API_KEY;
|
|
|
80
83
|
|
|
81
84
|
## How It Works
|
|
82
85
|
|
|
83
|
-
FivoSense uses **
|
|
84
|
-
|
|
85
|
-
1. **Graph Builder**: Parses code into data-flow graph
|
|
86
|
-
2. **Taint Tracker**: Traces untrusted input to dangerous sinks
|
|
87
|
-
3. **AI Judge**: Determines if paths are exploitable (coming soon)
|
|
88
|
-
4. **Proof Generator**: Creates exact evidence of vulnerability
|
|
86
|
+
FivoSense uses **AST-based taint analysis**:
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
1. **Graph Builder**: Parses code into data-flow graph using Babel parser
|
|
89
|
+
2. **Taint Tracker**: Traces untrusted input from source to dangerous sink
|
|
90
|
+
3. **Sanitization Check**: Detects if input is already sanitized (parseInt, execFile, etc.)
|
|
91
|
+
4. **AI Judge**: Verifies exploitability using OpenAI/Claude/Ollama (optional)
|
|
92
|
+
5. **Proof Generator**: Creates exact evidence with line numbers and CWE references
|
|
91
93
|
|
|
92
94
|
## Requirements
|
|
93
95
|
|
|
@@ -106,13 +108,14 @@ Configure in VS Code settings (File > Preferences > Settings):
|
|
|
106
108
|
}
|
|
107
109
|
```
|
|
108
110
|
|
|
109
|
-
## Known Issues
|
|
110
|
-
|
|
111
|
-
- Real-time scanning may have slight delay on large files
|
|
112
|
-
- Python support coming soon
|
|
113
|
-
|
|
114
111
|
## Release Notes
|
|
115
112
|
|
|
113
|
+
### 0.1.1
|
|
114
|
+
- Fixed vulnerability reporting structure
|
|
115
|
+
- Improved secret detection
|
|
116
|
+
- Added proper taint-trace proofs
|
|
117
|
+
- Updated to fivosense v0.1.6
|
|
118
|
+
|
|
116
119
|
### 0.1.0
|
|
117
120
|
- Initial release
|
|
118
121
|
- Real-time scanning for JS/TS
|
|
@@ -122,16 +125,18 @@ Configure in VS Code settings (File > Preferences > Settings):
|
|
|
122
125
|
|
|
123
126
|
## Contributing
|
|
124
127
|
|
|
125
|
-
See [CONTRIBUTING.md](https://github.com/
|
|
128
|
+
See [CONTRIBUTING.md](https://github.com/thevinsoni/sense/blob/main/CONTRIBUTING.md)
|
|
126
129
|
|
|
127
130
|
## License
|
|
128
131
|
|
|
129
|
-
MIT -
|
|
132
|
+
MIT License - Copyright © 2026 thevinsoni
|
|
133
|
+
|
|
134
|
+
See [LICENSE](https://github.com/thevinsoni/sense/blob/main/LICENSE)
|
|
130
135
|
|
|
131
136
|
## Support
|
|
132
137
|
|
|
133
|
-
- Issues: https://github.com/
|
|
134
|
-
- Discussions: https://github.com/
|
|
138
|
+
- Issues: https://github.com/thevinsoni/sense/issues
|
|
139
|
+
- Discussions: https://github.com/thevinsoni/sense/discussions
|
|
135
140
|
|
|
136
141
|
---
|
|
137
142
|
|
|
Binary file
|
|
Binary file
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fivosense-vscode",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "fivosense-vscode",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"fivosense": "^0.1.
|
|
12
|
+
"fivosense": "^0.1.6"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@types/node": "^20.11.0",
|
|
@@ -1224,9 +1224,9 @@
|
|
|
1224
1224
|
}
|
|
1225
1225
|
},
|
|
1226
1226
|
"node_modules/fivosense": {
|
|
1227
|
-
"version": "0.1.
|
|
1228
|
-
"resolved": "https://registry.npmjs.org/fivosense/-/fivosense-0.1.
|
|
1229
|
-
"integrity": "sha512-
|
|
1227
|
+
"version": "0.1.6",
|
|
1228
|
+
"resolved": "https://registry.npmjs.org/fivosense/-/fivosense-0.1.6.tgz",
|
|
1229
|
+
"integrity": "sha512-i5LAYS8c4adMRPXlN/lFbBZr4JwUJonECu//Uc8tEWQ3RZJbzI1IkApaly+ABqmUlblNSpQCMVMFh63pAr8zDw==",
|
|
1230
1230
|
"license": "MIT",
|
|
1231
1231
|
"dependencies": {
|
|
1232
1232
|
"@babel/parser": "^7.23.0",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"name": "fivosense-vscode",
|
|
3
3
|
"displayName": "FivoSense Security Scanner",
|
|
4
4
|
"description": "Real-time security vulnerability detection with AI-powered taint analysis",
|
|
5
|
-
"version": "0.1.
|
|
6
|
-
"publisher": "
|
|
5
|
+
"version": "0.1.1",
|
|
6
|
+
"publisher": "thevinsoni",
|
|
7
7
|
"engines": {
|
|
8
8
|
"vscode": "^1.80.0"
|
|
9
9
|
},
|
|
@@ -81,14 +81,16 @@
|
|
|
81
81
|
"typescript": "^5.3.3"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"fivosense": "^0.1.
|
|
84
|
+
"fivosense": "^0.1.6"
|
|
85
85
|
},
|
|
86
86
|
"repository": {
|
|
87
87
|
"type": "git",
|
|
88
|
-
"url": "https://github.com/
|
|
88
|
+
"url": "https://github.com/thevinsoni/sense.git"
|
|
89
89
|
},
|
|
90
90
|
"bugs": {
|
|
91
|
-
"url": "https://github.com/
|
|
91
|
+
"url": "https://github.com/thevinsoni/sense/issues"
|
|
92
92
|
},
|
|
93
|
+
"homepage": "https://github.com/thevinsoni/sense#readme",
|
|
94
|
+
"author": "thevinsoni",
|
|
93
95
|
"license": "MIT"
|
|
94
96
|
}
|
|
@@ -90,30 +90,35 @@ async function scanDocument(document: vscode.TextDocument) {
|
|
|
90
90
|
const result = await auditFile(document.uri.fsPath);
|
|
91
91
|
const diagnostics: vscode.Diagnostic[] = [];
|
|
92
92
|
|
|
93
|
-
// Convert
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const
|
|
93
|
+
// Convert vulnerabilities to VS Code diagnostics
|
|
94
|
+
for (const vuln of result.vulnerabilities) {
|
|
95
|
+
const severity = getSeverity(vuln.severity);
|
|
96
|
+
const line = vuln.location?.line || 1;
|
|
97
97
|
const range = new vscode.Range(
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
line - 1, 0,
|
|
99
|
+
line - 1, 1000
|
|
100
100
|
);
|
|
101
101
|
|
|
102
|
+
const evidenceText = vuln.evidence
|
|
103
|
+
?.filter((e: any) => e.line)
|
|
104
|
+
.map((e: any) => `${e.type} at line ${e.line}`)
|
|
105
|
+
.join(', ') || 'No evidence';
|
|
106
|
+
|
|
102
107
|
const diagnostic = new vscode.Diagnostic(
|
|
103
108
|
range,
|
|
104
|
-
`[${
|
|
109
|
+
`[${vuln.category}] ${vuln.finding}\n${evidenceText}`,
|
|
105
110
|
severity
|
|
106
111
|
);
|
|
107
112
|
|
|
108
|
-
diagnostic.code =
|
|
113
|
+
diagnostic.code = vuln.cwe;
|
|
109
114
|
diagnostic.source = 'FivoSense';
|
|
110
115
|
|
|
111
|
-
// Add
|
|
112
|
-
if (
|
|
116
|
+
// Add taint path as related info
|
|
117
|
+
if (vuln.path && vuln.path.length > 0) {
|
|
113
118
|
diagnostic.relatedInformation = [
|
|
114
119
|
new vscode.DiagnosticRelatedInformation(
|
|
115
120
|
new vscode.Location(document.uri, range),
|
|
116
|
-
`
|
|
121
|
+
`Taint path: ${vuln.path.join(' → ')}`
|
|
117
122
|
)
|
|
118
123
|
];
|
|
119
124
|
}
|
|
@@ -121,6 +126,55 @@ async function scanDocument(document: vscode.TextDocument) {
|
|
|
121
126
|
diagnostics.push(diagnostic);
|
|
122
127
|
}
|
|
123
128
|
|
|
129
|
+
// Convert secrets to VS Code diagnostics
|
|
130
|
+
for (const secret of result.secrets) {
|
|
131
|
+
const range = new vscode.Range(
|
|
132
|
+
secret.line - 1, 0,
|
|
133
|
+
secret.line - 1, 1000
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const diagnostic = new vscode.Diagnostic(
|
|
137
|
+
range,
|
|
138
|
+
`[Secret] ${secret.type} detected: ${secret.match}`,
|
|
139
|
+
vscode.DiagnosticSeverity.Warning
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
diagnostic.code = 'CWE-798';
|
|
143
|
+
diagnostic.source = 'FivoSense';
|
|
144
|
+
diagnostic.relatedInformation = [
|
|
145
|
+
new vscode.DiagnosticRelatedInformation(
|
|
146
|
+
new vscode.Location(document.uri, range),
|
|
147
|
+
'Fix: Use environment variables instead of hardcoded secrets'
|
|
148
|
+
)
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
diagnostics.push(diagnostic);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Convert destructive commands to VS Code diagnostics
|
|
155
|
+
for (const cmd of result.destructive) {
|
|
156
|
+
const range = new vscode.Range(
|
|
157
|
+
cmd.line - 1, 0,
|
|
158
|
+
cmd.line - 1, 1000
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const diagnostic = new vscode.Diagnostic(
|
|
162
|
+
range,
|
|
163
|
+
`[Destructive] ${cmd.command} - ${cmd.reason}`,
|
|
164
|
+
vscode.DiagnosticSeverity.Error
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
diagnostic.source = 'FivoSense';
|
|
168
|
+
diagnostic.relatedInformation = [
|
|
169
|
+
new vscode.DiagnosticRelatedInformation(
|
|
170
|
+
new vscode.Location(document.uri, range),
|
|
171
|
+
`Suggestion: ${cmd.suggestion}`
|
|
172
|
+
)
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
diagnostics.push(diagnostic);
|
|
176
|
+
}
|
|
177
|
+
|
|
124
178
|
diagnosticCollection.set(document.uri, diagnostics);
|
|
125
179
|
|
|
126
180
|
// Update status bar
|