supasec 1.0.4 → 1.0.5
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/Feature-List.md +233 -0
- package/README.md +53 -12
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +74 -18
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/snapshot.d.ts +32 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +282 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/reporters/html.d.ts +3 -2
- package/dist/reporters/html.d.ts.map +1 -1
- package/dist/reporters/html.js +844 -538
- package/dist/reporters/html.js.map +1 -1
- package/dist/reporters/terminal.d.ts +38 -2
- package/dist/reporters/terminal.d.ts.map +1 -1
- package/dist/reporters/terminal.js +292 -131
- package/dist/reporters/terminal.js.map +1 -1
- package/dist/scanners/auth/analyzer.d.ts +40 -0
- package/dist/scanners/auth/analyzer.d.ts.map +1 -0
- package/dist/scanners/auth/analyzer.js +673 -0
- package/dist/scanners/auth/analyzer.js.map +1 -0
- package/dist/scanners/auth/index.d.ts +6 -0
- package/dist/scanners/auth/index.d.ts.map +1 -0
- package/dist/scanners/auth/index.js +22 -0
- package/dist/scanners/auth/index.js.map +1 -0
- package/dist/scanners/edge/analyzer.d.ts +35 -0
- package/dist/scanners/edge/analyzer.d.ts.map +1 -0
- package/dist/scanners/edge/analyzer.js +614 -0
- package/dist/scanners/edge/analyzer.js.map +1 -0
- package/dist/scanners/edge/index.d.ts +6 -0
- package/dist/scanners/edge/index.d.ts.map +1 -0
- package/dist/scanners/edge/index.js +22 -0
- package/dist/scanners/edge/index.js.map +1 -0
- package/dist/scanners/functions/analyzer.d.ts +41 -0
- package/dist/scanners/functions/analyzer.d.ts.map +1 -0
- package/dist/scanners/functions/analyzer.js +378 -0
- package/dist/scanners/functions/analyzer.js.map +1 -0
- package/dist/scanners/functions/index.d.ts +6 -0
- package/dist/scanners/functions/index.d.ts.map +1 -0
- package/dist/scanners/functions/index.js +22 -0
- package/dist/scanners/functions/index.js.map +1 -0
- package/dist/scanners/git/index.d.ts +6 -0
- package/dist/scanners/git/index.d.ts.map +1 -0
- package/dist/scanners/git/index.js +22 -0
- package/dist/scanners/git/index.js.map +1 -0
- package/dist/scanners/git/scanner.d.ts +22 -0
- package/dist/scanners/git/scanner.d.ts.map +1 -0
- package/dist/scanners/git/scanner.js +531 -0
- package/dist/scanners/git/scanner.js.map +1 -0
- package/dist/scanners/https/analyzer.d.ts +42 -0
- package/dist/scanners/https/analyzer.d.ts.map +1 -0
- package/dist/scanners/https/analyzer.js +470 -0
- package/dist/scanners/https/analyzer.js.map +1 -0
- package/dist/scanners/https/index.d.ts +8 -0
- package/dist/scanners/https/index.d.ts.map +1 -0
- package/dist/scanners/https/index.js +17 -0
- package/dist/scanners/https/index.js.map +1 -0
- package/dist/scanners/index.d.ts +6 -0
- package/dist/scanners/index.d.ts.map +1 -1
- package/dist/scanners/index.js +6 -0
- package/dist/scanners/index.js.map +1 -1
- package/dist/scanners/rls/fuzzer.d.ts +40 -0
- package/dist/scanners/rls/fuzzer.d.ts.map +1 -0
- package/dist/scanners/rls/fuzzer.js +360 -0
- package/dist/scanners/rls/fuzzer.js.map +1 -0
- package/dist/scanners/rls/index.d.ts +1 -0
- package/dist/scanners/rls/index.d.ts.map +1 -1
- package/dist/scanners/rls/index.js +1 -0
- package/dist/scanners/rls/index.js.map +1 -1
- package/dist/scanners/secrets/detector.d.ts.map +1 -1
- package/dist/scanners/secrets/detector.js +44 -12
- package/dist/scanners/secrets/detector.js.map +1 -1
- package/dist/scanners/secrets/index.d.ts +1 -0
- package/dist/scanners/secrets/index.d.ts.map +1 -1
- package/dist/scanners/secrets/index.js +4 -0
- package/dist/scanners/secrets/index.js.map +1 -1
- package/dist/scanners/secrets/patterns.d.ts +25 -0
- package/dist/scanners/secrets/patterns.d.ts.map +1 -1
- package/dist/scanners/secrets/patterns.js +138 -27
- package/dist/scanners/secrets/patterns.js.map +1 -1
- package/dist/scanners/storage/analyzer.d.ts +49 -0
- package/dist/scanners/storage/analyzer.d.ts.map +1 -0
- package/dist/scanners/storage/analyzer.js +438 -0
- package/dist/scanners/storage/analyzer.js.map +1 -0
- package/dist/scanners/storage/index.d.ts +6 -0
- package/dist/scanners/storage/index.d.ts.map +1 -0
- package/dist/scanners/storage/index.js +22 -0
- package/dist/scanners/storage/index.js.map +1 -0
- package/package.json +1 -1
- package/reports/supasec-audityour-app-2026-01-28-19-42-22.html +757 -0
- package/reports/supasec-audityour-app-2026-01-28-19-49-18.html +1122 -0
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Edge Function Analyzer
|
|
4
|
+
* Scans Supabase Edge Functions for security issues and secrets
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.analyzeEdgeFunctions = analyzeEdgeFunctions;
|
|
8
|
+
exports.getMockEdgeFunctions = getMockEdgeFunctions;
|
|
9
|
+
const finding_js_1 = require("../../models/finding.js");
|
|
10
|
+
/**
|
|
11
|
+
* Analyze Edge Functions for security issues
|
|
12
|
+
*/
|
|
13
|
+
async function analyzeEdgeFunctions(options) {
|
|
14
|
+
const findings = [];
|
|
15
|
+
let findingCounter = 1;
|
|
16
|
+
let vulnerableCount = 0;
|
|
17
|
+
for (const func of options.functions) {
|
|
18
|
+
let functionHasIssues = false;
|
|
19
|
+
// Check for secrets in code
|
|
20
|
+
const secretFindings = scanForSecretsInCode(func, findingCounter);
|
|
21
|
+
findings.push(...secretFindings.findings);
|
|
22
|
+
findingCounter = secretFindings.nextCounter;
|
|
23
|
+
if (secretFindings.findings.length > 0)
|
|
24
|
+
functionHasIssues = true;
|
|
25
|
+
// Check for hardcoded credentials
|
|
26
|
+
const credentialFindings = scanForHardcodedCredentials(func, findingCounter);
|
|
27
|
+
findings.push(...credentialFindings.findings);
|
|
28
|
+
findingCounter = credentialFindings.nextCounter;
|
|
29
|
+
if (credentialFindings.findings.length > 0)
|
|
30
|
+
functionHasIssues = true;
|
|
31
|
+
// Check for missing auth
|
|
32
|
+
if (!func.authRequired) {
|
|
33
|
+
findings.push(createMissingAuthFinding(func, findingCounter++));
|
|
34
|
+
functionHasIssues = true;
|
|
35
|
+
}
|
|
36
|
+
// Check for CORS issues
|
|
37
|
+
if (func.corsEnabled === false) {
|
|
38
|
+
findings.push(createCORSIssueFinding(func, findingCounter++));
|
|
39
|
+
}
|
|
40
|
+
// Check for dangerous imports
|
|
41
|
+
const importFindings = scanForDangerousImports(func, findingCounter);
|
|
42
|
+
findings.push(...importFindings.findings);
|
|
43
|
+
findingCounter = importFindings.nextCounter;
|
|
44
|
+
if (importFindings.findings.length > 0)
|
|
45
|
+
functionHasIssues = true;
|
|
46
|
+
// Check for SQL injection risks
|
|
47
|
+
const sqlInjectionFindings = scanForSQLInjectionRisk(func, findingCounter);
|
|
48
|
+
findings.push(...sqlInjectionFindings.findings);
|
|
49
|
+
findingCounter = sqlInjectionFindings.nextCounter;
|
|
50
|
+
if (sqlInjectionFindings.findings.length > 0)
|
|
51
|
+
functionHasIssues = true;
|
|
52
|
+
if (functionHasIssues) {
|
|
53
|
+
vulnerableCount++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
findings,
|
|
58
|
+
functionsScanned: options.functions.length,
|
|
59
|
+
vulnerableFunctions: vulnerableCount
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Scan Edge Function code for secrets
|
|
64
|
+
*/
|
|
65
|
+
function scanForSecretsInCode(func, startCounter) {
|
|
66
|
+
const findings = [];
|
|
67
|
+
let counter = startCounter;
|
|
68
|
+
const secretPatterns = [
|
|
69
|
+
{ pattern: /supabaseKey\s*[:=]\s*["']([^"']+)["']/i, type: 'Supabase Key' },
|
|
70
|
+
{ pattern: /serviceRoleKey\s*[:=]\s*["']([^"']+)["']/i, type: 'Service Role Key' },
|
|
71
|
+
{ pattern: /apiKey\s*[:=]\s*["']([^"']+)["']/i, type: 'API Key' },
|
|
72
|
+
{ pattern: /password\s*[:=]\s*["']([^"']+)["']/i, type: 'Password' },
|
|
73
|
+
{ pattern: /secret\s*[:=]\s*["']([^"']+)["']/i, type: 'Secret' },
|
|
74
|
+
{ pattern: /token\s*[:=]\s*["']([^"']+)["']/i, type: 'Token' },
|
|
75
|
+
{ pattern: /sk-[a-zA-Z0-9]{48}/, type: 'Stripe Key' },
|
|
76
|
+
{ pattern: /AKIA[0-9A-Z]{16}/, type: 'AWS Access Key' },
|
|
77
|
+
{ pattern: /eyJ[A-Za-z0-9-_]*\.eyJ[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*/, type: 'JWT Token' }
|
|
78
|
+
];
|
|
79
|
+
for (const { pattern, type } of secretPatterns) {
|
|
80
|
+
const match = func.content.match(pattern);
|
|
81
|
+
if (match) {
|
|
82
|
+
findings.push(createEdgeSecretFinding(func, type, match[0], counter++));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { findings, nextCounter: counter };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Scan for hardcoded credentials
|
|
89
|
+
*/
|
|
90
|
+
function scanForHardcodedCredentials(func, startCounter) {
|
|
91
|
+
const findings = [];
|
|
92
|
+
let counter = startCounter;
|
|
93
|
+
// Check for hardcoded URLs with credentials
|
|
94
|
+
const urlPattern = /https?:\/\/[^:]+:[^@]+@[^\s"']+/g;
|
|
95
|
+
const matches = func.content.match(urlPattern);
|
|
96
|
+
if (matches) {
|
|
97
|
+
for (const match of matches) {
|
|
98
|
+
findings.push(createHardcodedURLFinding(func, match, counter++));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Check for env var usage that might be hardcoded
|
|
102
|
+
if (func.envVars.length === 0 && func.hasSecrets) {
|
|
103
|
+
findings.push(createNoEnvVarsFinding(func, counter++));
|
|
104
|
+
}
|
|
105
|
+
return { findings, nextCounter: counter };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Scan for dangerous imports
|
|
109
|
+
*/
|
|
110
|
+
function scanForDangerousImports(func, startCounter) {
|
|
111
|
+
const findings = [];
|
|
112
|
+
let counter = startCounter;
|
|
113
|
+
const dangerousImports = [
|
|
114
|
+
{ pattern: /eval\s*\(/, type: 'eval()', severity: 'HIGH' },
|
|
115
|
+
{ pattern: /new\s+Function\s*\(/, type: 'Function constructor', severity: 'HIGH' },
|
|
116
|
+
{ pattern: /child_process/, type: 'child_process', severity: 'CRITICAL' },
|
|
117
|
+
{ pattern: /fs\.writeFileSync.*req\./, type: 'File write from request', severity: 'HIGH' },
|
|
118
|
+
{ pattern: /exec\s*\(/, type: 'exec()', severity: 'CRITICAL' }
|
|
119
|
+
];
|
|
120
|
+
for (const { pattern, type, severity } of dangerousImports) {
|
|
121
|
+
if (pattern.test(func.content)) {
|
|
122
|
+
findings.push(createDangerousImportFinding(func, type, severity, counter++));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { findings, nextCounter: counter };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Scan for SQL injection risks
|
|
129
|
+
*/
|
|
130
|
+
function scanForSQLInjectionRisk(func, startCounter) {
|
|
131
|
+
const findings = [];
|
|
132
|
+
let counter = startCounter;
|
|
133
|
+
// Check for raw SQL with request parameters
|
|
134
|
+
const sqlPatterns = [
|
|
135
|
+
/supabase\.rpc\s*\(\s*["'][^"']+["']\s*,\s*\{[^}]*req\./,
|
|
136
|
+
/supabase\.from\s*\(\s*["'][^"']+["']\s*\)\.select\s*\(\s*["'][^"']*["']\s*\).*req\./,
|
|
137
|
+
/query\s*\(\s*[`"'][^`"']*\$\{[^}]*req\./
|
|
138
|
+
];
|
|
139
|
+
for (const pattern of sqlPatterns) {
|
|
140
|
+
if (pattern.test(func.content)) {
|
|
141
|
+
findings.push(createSQLInjectionRiskFinding(func, counter++));
|
|
142
|
+
break; // Only report once per function
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return { findings, nextCounter: counter };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create finding for secret in Edge Function
|
|
149
|
+
*/
|
|
150
|
+
function createEdgeSecretFinding(func, type, match, counter) {
|
|
151
|
+
return {
|
|
152
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
153
|
+
timestamp: new Date().toISOString(),
|
|
154
|
+
severity: 'CRITICAL',
|
|
155
|
+
category: 'functions',
|
|
156
|
+
subcategory: 'edge_secret',
|
|
157
|
+
title: `${type} exposed in Edge Function '${func.name}'`,
|
|
158
|
+
description: `A ${type} was found hardcoded in the Edge Function '${func.name}'. Edge Functions are deployed to the edge and their code can be inspected.`,
|
|
159
|
+
location: {
|
|
160
|
+
file: func.path,
|
|
161
|
+
line: 1
|
|
162
|
+
},
|
|
163
|
+
evidence: {
|
|
164
|
+
function_name: func.name,
|
|
165
|
+
function_path: func.path,
|
|
166
|
+
secret_type: type,
|
|
167
|
+
matched_text: match.substring(0, 30) + '...'
|
|
168
|
+
},
|
|
169
|
+
impact: {
|
|
170
|
+
severity_score: 9.5,
|
|
171
|
+
description: 'Secret exposed in Edge Function code - anyone can view deployed function code',
|
|
172
|
+
affected_resources: [`edge:${func.name}`],
|
|
173
|
+
compliance_violations: ['OWASP-A05-2021', 'GDPR-Article-32']
|
|
174
|
+
},
|
|
175
|
+
remediation: {
|
|
176
|
+
summary: `Move ${type} to environment variables`,
|
|
177
|
+
priority: 'IMMEDIATE',
|
|
178
|
+
effort: 'LOW',
|
|
179
|
+
steps: [
|
|
180
|
+
{
|
|
181
|
+
order: 1,
|
|
182
|
+
action: 'Use Deno.env.get() instead of hardcoded values',
|
|
183
|
+
code: `// Instead of:
|
|
184
|
+
const supabaseKey = "${match.substring(0, 20)}...";
|
|
185
|
+
|
|
186
|
+
// Use:
|
|
187
|
+
const supabaseKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;`
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
order: 2,
|
|
191
|
+
action: 'Set environment variable in Supabase Dashboard',
|
|
192
|
+
code: 'Go to Project Settings > Edge Functions > Environment Variables'
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
order: 3,
|
|
196
|
+
action: 'Rotate the exposed secret',
|
|
197
|
+
code: 'Generate a new key and revoke the old one'
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
auto_fixable: false
|
|
201
|
+
},
|
|
202
|
+
references: [
|
|
203
|
+
{
|
|
204
|
+
title: 'Supabase Edge Functions Environment Variables',
|
|
205
|
+
url: 'https://supabase.com/docs/guides/functions/secrets'
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
false_positive_likelihood: 'LOW',
|
|
209
|
+
confidence: 0.95
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create finding for hardcoded URL with credentials
|
|
214
|
+
*/
|
|
215
|
+
function createHardcodedURLFinding(func, url, counter) {
|
|
216
|
+
return {
|
|
217
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
218
|
+
timestamp: new Date().toISOString(),
|
|
219
|
+
severity: 'CRITICAL',
|
|
220
|
+
category: 'functions',
|
|
221
|
+
subcategory: 'hardcoded_url',
|
|
222
|
+
title: `Hardcoded credentials in URL in '${func.name}'`,
|
|
223
|
+
description: `A URL with embedded credentials was found in the Edge Function '${func.name}'. This exposes authentication information.`,
|
|
224
|
+
location: {
|
|
225
|
+
file: func.path,
|
|
226
|
+
line: 1
|
|
227
|
+
},
|
|
228
|
+
evidence: {
|
|
229
|
+
function_name: func.name,
|
|
230
|
+
function_path: func.path,
|
|
231
|
+
url_pattern: url.replace(/:[^@]+@/, ':***@')
|
|
232
|
+
},
|
|
233
|
+
impact: {
|
|
234
|
+
severity_score: 9.0,
|
|
235
|
+
description: 'Credentials exposed in URL - full account compromise possible',
|
|
236
|
+
affected_resources: [`edge:${func.name}`]
|
|
237
|
+
},
|
|
238
|
+
remediation: {
|
|
239
|
+
summary: 'Remove credentials from URL and use environment variables',
|
|
240
|
+
priority: 'IMMEDIATE',
|
|
241
|
+
effort: 'LOW',
|
|
242
|
+
steps: [
|
|
243
|
+
{
|
|
244
|
+
order: 1,
|
|
245
|
+
action: 'Extract credentials to environment variables',
|
|
246
|
+
code: `// Instead of:
|
|
247
|
+
const url = "${url.replace(/:[^@]+@/, ':***@')}";
|
|
248
|
+
|
|
249
|
+
// Use:
|
|
250
|
+
const username = Deno.env.get("DB_USERNAME")!;
|
|
251
|
+
const password = Deno.env.get("DB_PASSWORD")!;
|
|
252
|
+
const url = \`https://\${username}:\${password}@host.com\`;`
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
auto_fixable: false
|
|
256
|
+
},
|
|
257
|
+
references: [],
|
|
258
|
+
false_positive_likelihood: 'LOW',
|
|
259
|
+
confidence: 0.9
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Create finding for missing env vars
|
|
264
|
+
*/
|
|
265
|
+
function createNoEnvVarsFinding(func, counter) {
|
|
266
|
+
return {
|
|
267
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
268
|
+
timestamp: new Date().toISOString(),
|
|
269
|
+
severity: 'MEDIUM',
|
|
270
|
+
category: 'functions',
|
|
271
|
+
subcategory: 'no_env_vars',
|
|
272
|
+
title: `Edge Function '${func.name}' may have hardcoded secrets`,
|
|
273
|
+
description: `The Edge Function '${func.name}' appears to contain secrets but doesn't use environment variables. This suggests hardcoded credentials.`,
|
|
274
|
+
location: {
|
|
275
|
+
file: func.path
|
|
276
|
+
},
|
|
277
|
+
evidence: {
|
|
278
|
+
function_name: func.name,
|
|
279
|
+
env_vars_used: func.envVars.length
|
|
280
|
+
},
|
|
281
|
+
impact: {
|
|
282
|
+
severity_score: 6.0,
|
|
283
|
+
description: 'Potential hardcoded secrets - code review recommended',
|
|
284
|
+
affected_resources: [`edge:${func.name}`]
|
|
285
|
+
},
|
|
286
|
+
remediation: {
|
|
287
|
+
summary: 'Review function for hardcoded secrets',
|
|
288
|
+
priority: 'MEDIUM',
|
|
289
|
+
effort: 'LOW',
|
|
290
|
+
steps: [
|
|
291
|
+
{
|
|
292
|
+
order: 1,
|
|
293
|
+
action: 'Review function code for hardcoded values',
|
|
294
|
+
code: `grep -n "password\|secret\|key\|token" ${func.path}`
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
order: 2,
|
|
298
|
+
action: 'Move secrets to environment variables',
|
|
299
|
+
code: 'Use Deno.env.get() for all sensitive values'
|
|
300
|
+
}
|
|
301
|
+
],
|
|
302
|
+
auto_fixable: false
|
|
303
|
+
},
|
|
304
|
+
references: [],
|
|
305
|
+
false_positive_likelihood: 'HIGH',
|
|
306
|
+
confidence: 0.6
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Create finding for missing auth
|
|
311
|
+
*/
|
|
312
|
+
function createMissingAuthFinding(func, counter) {
|
|
313
|
+
return {
|
|
314
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
315
|
+
timestamp: new Date().toISOString(),
|
|
316
|
+
severity: 'HIGH',
|
|
317
|
+
category: 'functions',
|
|
318
|
+
subcategory: 'missing_auth',
|
|
319
|
+
title: `Edge Function '${func.name}' lacks authentication`,
|
|
320
|
+
description: `The Edge Function '${func.name}' does not appear to require authentication. This may allow unauthorized access to sensitive operations.`,
|
|
321
|
+
location: {
|
|
322
|
+
file: func.path
|
|
323
|
+
},
|
|
324
|
+
evidence: {
|
|
325
|
+
function_name: func.name,
|
|
326
|
+
auth_required: false
|
|
327
|
+
},
|
|
328
|
+
impact: {
|
|
329
|
+
severity_score: 7.5,
|
|
330
|
+
description: 'Unauthenticated access to Edge Function - potential data breach',
|
|
331
|
+
affected_resources: [`edge:${func.name}`]
|
|
332
|
+
},
|
|
333
|
+
remediation: {
|
|
334
|
+
summary: 'Add authentication to Edge Function',
|
|
335
|
+
priority: 'HIGH',
|
|
336
|
+
effort: 'MEDIUM',
|
|
337
|
+
steps: [
|
|
338
|
+
{
|
|
339
|
+
order: 1,
|
|
340
|
+
action: 'Add JWT verification',
|
|
341
|
+
code: `import { createClient } from '@supabase/supabase-js';
|
|
342
|
+
|
|
343
|
+
Deno.serve(async (req) => {
|
|
344
|
+
const authHeader = req.headers.get('Authorization');
|
|
345
|
+
if (!authHeader) {
|
|
346
|
+
return new Response('Unauthorized', { status: 401 });
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Verify JWT with Supabase
|
|
350
|
+
const supabase = createClient(
|
|
351
|
+
Deno.env.get('SUPABASE_URL')!,
|
|
352
|
+
Deno.env.get('SUPABASE_ANON_KEY')!
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
const { data: { user }, error } = await supabase.auth.getUser(
|
|
356
|
+
authHeader.replace('Bearer ', '')
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
if (error || !user) {
|
|
360
|
+
return new Response('Unauthorized', { status: 401 });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Continue with authenticated request...
|
|
364
|
+
});`
|
|
365
|
+
}
|
|
366
|
+
],
|
|
367
|
+
auto_fixable: false
|
|
368
|
+
},
|
|
369
|
+
references: [
|
|
370
|
+
{
|
|
371
|
+
title: 'Supabase Edge Functions Auth',
|
|
372
|
+
url: 'https://supabase.com/docs/guides/functions/auth'
|
|
373
|
+
}
|
|
374
|
+
],
|
|
375
|
+
false_positive_likelihood: 'MEDIUM',
|
|
376
|
+
confidence: 0.7
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Create finding for CORS issues
|
|
381
|
+
*/
|
|
382
|
+
function createCORSIssueFinding(func, counter) {
|
|
383
|
+
return {
|
|
384
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
385
|
+
timestamp: new Date().toISOString(),
|
|
386
|
+
severity: 'MEDIUM',
|
|
387
|
+
category: 'functions',
|
|
388
|
+
subcategory: 'cors_disabled',
|
|
389
|
+
title: `Edge Function '${func.name}' has CORS disabled`,
|
|
390
|
+
description: `The Edge Function '${func.name}' does not have CORS enabled. This may prevent legitimate cross-origin requests or indicate overly permissive settings.`,
|
|
391
|
+
location: {
|
|
392
|
+
file: func.path
|
|
393
|
+
},
|
|
394
|
+
evidence: {
|
|
395
|
+
function_name: func.name,
|
|
396
|
+
cors_enabled: false
|
|
397
|
+
},
|
|
398
|
+
impact: {
|
|
399
|
+
severity_score: 5.0,
|
|
400
|
+
description: 'CORS issues may affect functionality or security',
|
|
401
|
+
affected_resources: [`edge:${func.name}`]
|
|
402
|
+
},
|
|
403
|
+
remediation: {
|
|
404
|
+
summary: 'Configure appropriate CORS headers',
|
|
405
|
+
priority: 'MEDIUM',
|
|
406
|
+
effort: 'LOW',
|
|
407
|
+
steps: [
|
|
408
|
+
{
|
|
409
|
+
order: 1,
|
|
410
|
+
action: 'Add CORS headers',
|
|
411
|
+
code: `Deno.serve(async (req) => {
|
|
412
|
+
// Handle CORS preflight
|
|
413
|
+
if (req.method === 'OPTIONS') {
|
|
414
|
+
return new Response('ok', {
|
|
415
|
+
headers: {
|
|
416
|
+
'Access-Control-Allow-Origin': '*',
|
|
417
|
+
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
|
418
|
+
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type'
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Handle actual request...
|
|
424
|
+
const response = await handleRequest(req);
|
|
425
|
+
|
|
426
|
+
// Add CORS headers to response
|
|
427
|
+
response.headers.set('Access-Control-Allow-Origin', '*');
|
|
428
|
+
return response;
|
|
429
|
+
});`
|
|
430
|
+
}
|
|
431
|
+
],
|
|
432
|
+
auto_fixable: true
|
|
433
|
+
},
|
|
434
|
+
references: [
|
|
435
|
+
{
|
|
436
|
+
title: 'CORS on Supabase Edge Functions',
|
|
437
|
+
url: 'https://supabase.com/docs/guides/functions/cors'
|
|
438
|
+
}
|
|
439
|
+
],
|
|
440
|
+
false_positive_likelihood: 'HIGH',
|
|
441
|
+
confidence: 0.6
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Create finding for dangerous imports
|
|
446
|
+
*/
|
|
447
|
+
function createDangerousImportFinding(func, type, severity, counter) {
|
|
448
|
+
return {
|
|
449
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
450
|
+
timestamp: new Date().toISOString(),
|
|
451
|
+
severity,
|
|
452
|
+
category: 'functions',
|
|
453
|
+
subcategory: 'dangerous_import',
|
|
454
|
+
title: `Dangerous ${type} usage in '${func.name}'`,
|
|
455
|
+
description: `The Edge Function '${func.name}' uses ${type} which can lead to code injection or remote code execution.`,
|
|
456
|
+
location: {
|
|
457
|
+
file: func.path
|
|
458
|
+
},
|
|
459
|
+
evidence: {
|
|
460
|
+
function_name: func.name,
|
|
461
|
+
dangerous_feature: type
|
|
462
|
+
},
|
|
463
|
+
impact: {
|
|
464
|
+
severity_score: severity === 'CRITICAL' ? 9.5 : 8.0,
|
|
465
|
+
description: 'Code injection risk - potential for remote code execution',
|
|
466
|
+
affected_resources: [`edge:${func.name}`],
|
|
467
|
+
compliance_violations: ['OWASP-A03-2021']
|
|
468
|
+
},
|
|
469
|
+
remediation: {
|
|
470
|
+
summary: `Remove ${type} and use safer alternatives`,
|
|
471
|
+
priority: 'IMMEDIATE',
|
|
472
|
+
effort: 'MEDIUM',
|
|
473
|
+
steps: [
|
|
474
|
+
{
|
|
475
|
+
order: 1,
|
|
476
|
+
action: 'Replace with safe alternatives',
|
|
477
|
+
code: `// Instead of eval():
|
|
478
|
+
const result = eval(userInput);
|
|
479
|
+
|
|
480
|
+
// Use JSON.parse for JSON:
|
|
481
|
+
const result = JSON.parse(userInput);
|
|
482
|
+
|
|
483
|
+
// Or validate input strictly:
|
|
484
|
+
const allowedOperations = ['add', 'subtract'];
|
|
485
|
+
if (!allowedOperations.includes(userInput)) {
|
|
486
|
+
throw new Error('Invalid operation');
|
|
487
|
+
}`
|
|
488
|
+
}
|
|
489
|
+
],
|
|
490
|
+
auto_fixable: false
|
|
491
|
+
},
|
|
492
|
+
references: [
|
|
493
|
+
{
|
|
494
|
+
title: 'OWASP Code Injection Prevention',
|
|
495
|
+
url: 'https://cheatsheetseries.owasp.org/cheatsheets/Code_Injection_Prevention_Cheat_Sheet.html'
|
|
496
|
+
}
|
|
497
|
+
],
|
|
498
|
+
false_positive_likelihood: 'LOW',
|
|
499
|
+
confidence: 0.9
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Create finding for SQL injection risk
|
|
504
|
+
*/
|
|
505
|
+
function createSQLInjectionRiskFinding(func, counter) {
|
|
506
|
+
return {
|
|
507
|
+
finding_id: (0, finding_js_1.generateFindingId)('functions', counter),
|
|
508
|
+
timestamp: new Date().toISOString(),
|
|
509
|
+
severity: 'HIGH',
|
|
510
|
+
category: 'functions',
|
|
511
|
+
subcategory: 'sql_injection',
|
|
512
|
+
title: `Potential SQL injection in '${func.name}'`,
|
|
513
|
+
description: `The Edge Function '${func.name}' appears to use request parameters in database queries without proper sanitization.`,
|
|
514
|
+
location: {
|
|
515
|
+
file: func.path
|
|
516
|
+
},
|
|
517
|
+
evidence: {
|
|
518
|
+
function_name: func.name
|
|
519
|
+
},
|
|
520
|
+
impact: {
|
|
521
|
+
severity_score: 8.0,
|
|
522
|
+
description: 'SQL injection vulnerability - potential for data breach',
|
|
523
|
+
affected_resources: [`edge:${func.name}`],
|
|
524
|
+
compliance_violations: ['OWASP-A03-2021']
|
|
525
|
+
},
|
|
526
|
+
remediation: {
|
|
527
|
+
summary: 'Use parameterized queries',
|
|
528
|
+
priority: 'HIGH',
|
|
529
|
+
effort: 'MEDIUM',
|
|
530
|
+
steps: [
|
|
531
|
+
{
|
|
532
|
+
order: 1,
|
|
533
|
+
action: 'Use Supabase RPC with parameters',
|
|
534
|
+
code: `// Instead of:
|
|
535
|
+
const { data } = await supabase
|
|
536
|
+
.from('users')
|
|
537
|
+
.select('*')
|
|
538
|
+
.eq('id', req.body.userId); // Risky
|
|
539
|
+
|
|
540
|
+
// Use RPC with validation:
|
|
541
|
+
const userId = req.body.userId;
|
|
542
|
+
if (!/^[0-9a-f-]{36}$/.test(userId)) {
|
|
543
|
+
return new Response('Invalid ID', { status: 400 });
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const { data } = await supabase
|
|
547
|
+
.from('users')
|
|
548
|
+
.select('*')
|
|
549
|
+
.eq('id', userId);`
|
|
550
|
+
}
|
|
551
|
+
],
|
|
552
|
+
auto_fixable: false
|
|
553
|
+
},
|
|
554
|
+
references: [
|
|
555
|
+
{
|
|
556
|
+
title: 'OWASP SQL Injection Prevention',
|
|
557
|
+
url: 'https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html'
|
|
558
|
+
}
|
|
559
|
+
],
|
|
560
|
+
false_positive_likelihood: 'MEDIUM',
|
|
561
|
+
confidence: 0.75
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Get mock Edge Functions for testing
|
|
566
|
+
*/
|
|
567
|
+
function getMockEdgeFunctions() {
|
|
568
|
+
return [
|
|
569
|
+
{
|
|
570
|
+
name: 'hello-world',
|
|
571
|
+
path: 'supabase/functions/hello-world/index.ts',
|
|
572
|
+
content: `
|
|
573
|
+
import { createClient } from '@supabase/supabase-js';
|
|
574
|
+
|
|
575
|
+
const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
|
|
576
|
+
|
|
577
|
+
Deno.serve(async (req) => {
|
|
578
|
+
const { name } = await req.json();
|
|
579
|
+
return new Response(\`Hello \${name}!\`);
|
|
580
|
+
});
|
|
581
|
+
`,
|
|
582
|
+
imports: ['@supabase/supabase-js'],
|
|
583
|
+
envVars: [],
|
|
584
|
+
hasSecrets: true,
|
|
585
|
+
httpMethods: ['POST', 'GET'],
|
|
586
|
+
corsEnabled: true,
|
|
587
|
+
authRequired: false
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
name: 'process-data',
|
|
591
|
+
path: 'supabase/functions/process-data/index.ts',
|
|
592
|
+
content: `
|
|
593
|
+
Deno.serve(async (req) => {
|
|
594
|
+
const authHeader = req.headers.get('Authorization');
|
|
595
|
+
if (!authHeader) {
|
|
596
|
+
return new Response('Unauthorized', { status: 401 });
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const { data } = await req.json();
|
|
600
|
+
const result = eval(data.expression); // Dangerous!
|
|
601
|
+
|
|
602
|
+
return new Response(JSON.stringify(result));
|
|
603
|
+
});
|
|
604
|
+
`,
|
|
605
|
+
imports: [],
|
|
606
|
+
envVars: ['SUPABASE_URL'],
|
|
607
|
+
hasSecrets: false,
|
|
608
|
+
httpMethods: ['POST'],
|
|
609
|
+
corsEnabled: false,
|
|
610
|
+
authRequired: true
|
|
611
|
+
}
|
|
612
|
+
];
|
|
613
|
+
}
|
|
614
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/scanners/edge/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/edge/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Edge Functions Scanner Module
|
|
4
|
+
* Export all Edge Function analysis functionality
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./analyzer"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/edge/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;AAEH,6CAA2B"}
|