@datahogo/core 0.1.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 +661 -0
- package/README.md +17 -0
- package/dist/engines/config.d.ts +3 -0
- package/dist/engines/config.d.ts.map +1 -0
- package/dist/engines/config.js +433 -0
- package/dist/engines/config.js.map +1 -0
- package/dist/engines/dast.d.ts +3 -0
- package/dist/engines/dast.d.ts.map +1 -0
- package/dist/engines/dast.js +167 -0
- package/dist/engines/dast.js.map +1 -0
- package/dist/engines/db-rules.d.ts +3 -0
- package/dist/engines/db-rules.d.ts.map +1 -0
- package/dist/engines/db-rules.js +166 -0
- package/dist/engines/db-rules.js.map +1 -0
- package/dist/engines/dependencies.d.ts +3 -0
- package/dist/engines/dependencies.d.ts.map +1 -0
- package/dist/engines/dependencies.js +167 -0
- package/dist/engines/dependencies.js.map +1 -0
- package/dist/engines/github-actions.d.ts +3 -0
- package/dist/engines/github-actions.d.ts.map +1 -0
- package/dist/engines/github-actions.js +215 -0
- package/dist/engines/github-actions.js.map +1 -0
- package/dist/engines/gitleaks.d.ts +3 -0
- package/dist/engines/gitleaks.d.ts.map +1 -0
- package/dist/engines/gitleaks.js +107 -0
- package/dist/engines/gitleaks.js.map +1 -0
- package/dist/engines/npm-audit.d.ts +3 -0
- package/dist/engines/npm-audit.d.ts.map +1 -0
- package/dist/engines/npm-audit.js +113 -0
- package/dist/engines/npm-audit.js.map +1 -0
- package/dist/engines/patterns.d.ts +3 -0
- package/dist/engines/patterns.d.ts.map +1 -0
- package/dist/engines/patterns.js +1330 -0
- package/dist/engines/patterns.js.map +1 -0
- package/dist/engines/secrets.d.ts +4 -0
- package/dist/engines/secrets.d.ts.map +1 -0
- package/dist/engines/secrets.js +260 -0
- package/dist/engines/secrets.js.map +1 -0
- package/dist/engines/semgrep.d.ts +3 -0
- package/dist/engines/semgrep.d.ts.map +1 -0
- package/dist/engines/semgrep.js +173 -0
- package/dist/engines/semgrep.js.map +1 -0
- package/dist/engines/types.d.ts +30 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +3 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/engines/url-scanner.d.ts +3 -0
- package/dist/engines/url-scanner.d.ts.map +1 -0
- package/dist/engines/url-scanner.js +469 -0
- package/dist/engines/url-scanner.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +32 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +237 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/rules/.gitkeep +0 -0
- package/dist/rules/ai-llm-security.yaml +199 -0
- package/dist/rules/api-security.yaml +489 -0
- package/dist/rules/auth-patterns.yaml +406 -0
- package/dist/rules/crypto-patterns.yaml +227 -0
- package/dist/rules/database-cloud-security.yaml +169 -0
- package/dist/rules/general-security.yaml +588 -0
- package/dist/rules/injection-patterns.yaml +318 -0
- package/dist/rules/nextjs-security.yaml +532 -0
- package/dist/rules/node-security.yaml +380 -0
- package/dist/rules/rules/.gitkeep +0 -0
- package/dist/rules/rules/ai-llm-security.yaml +199 -0
- package/dist/rules/rules/api-security.yaml +489 -0
- package/dist/rules/rules/auth-patterns.yaml +406 -0
- package/dist/rules/rules/crypto-patterns.yaml +227 -0
- package/dist/rules/rules/database-cloud-security.yaml +169 -0
- package/dist/rules/rules/general-security.yaml +588 -0
- package/dist/rules/rules/injection-patterns.yaml +318 -0
- package/dist/rules/rules/nextjs-security.yaml +532 -0
- package/dist/rules/rules/node-security.yaml +380 -0
- package/dist/rules/rules/supabase-security.yaml +387 -0
- package/dist/rules/supabase-security.yaml +387 -0
- package/dist/scanning/agents/csharp-agent.d.ts +12 -0
- package/dist/scanning/agents/csharp-agent.d.ts.map +1 -0
- package/dist/scanning/agents/csharp-agent.js +592 -0
- package/dist/scanning/agents/csharp-agent.js.map +1 -0
- package/dist/scanning/agents/go-agent.d.ts +14 -0
- package/dist/scanning/agents/go-agent.d.ts.map +1 -0
- package/dist/scanning/agents/go-agent.js +641 -0
- package/dist/scanning/agents/go-agent.js.map +1 -0
- package/dist/scanning/agents/java-agent.d.ts +8 -0
- package/dist/scanning/agents/java-agent.d.ts.map +1 -0
- package/dist/scanning/agents/java-agent.js +807 -0
- package/dist/scanning/agents/java-agent.js.map +1 -0
- package/dist/scanning/agents/javascript-agent.d.ts +8 -0
- package/dist/scanning/agents/javascript-agent.d.ts.map +1 -0
- package/dist/scanning/agents/javascript-agent.js +77 -0
- package/dist/scanning/agents/javascript-agent.js.map +1 -0
- package/dist/scanning/agents/mobile-agent.d.ts +8 -0
- package/dist/scanning/agents/mobile-agent.d.ts.map +1 -0
- package/dist/scanning/agents/mobile-agent.js +916 -0
- package/dist/scanning/agents/mobile-agent.js.map +1 -0
- package/dist/scanning/agents/php-agent.d.ts +8 -0
- package/dist/scanning/agents/php-agent.d.ts.map +1 -0
- package/dist/scanning/agents/php-agent.js +679 -0
- package/dist/scanning/agents/php-agent.js.map +1 -0
- package/dist/scanning/agents/python-agent.d.ts +8 -0
- package/dist/scanning/agents/python-agent.d.ts.map +1 -0
- package/dist/scanning/agents/python-agent.js +701 -0
- package/dist/scanning/agents/python-agent.js.map +1 -0
- package/dist/scanning/agents/supabase-agent.d.ts +8 -0
- package/dist/scanning/agents/supabase-agent.d.ts.map +1 -0
- package/dist/scanning/agents/supabase-agent.js +484 -0
- package/dist/scanning/agents/supabase-agent.js.map +1 -0
- package/dist/scanning/orchestrator.d.ts +29 -0
- package/dist/scanning/orchestrator.d.ts.map +1 -0
- package/dist/scanning/orchestrator.js +186 -0
- package/dist/scanning/orchestrator.js.map +1 -0
- package/dist/scanning/tech-detector.d.ts +12 -0
- package/dist/scanning/tech-detector.d.ts.map +1 -0
- package/dist/scanning/tech-detector.js +252 -0
- package/dist/scanning/tech-detector.js.map +1 -0
- package/dist/scanning/types.d.ts +87 -0
- package/dist/scanning/types.d.ts.map +1 -0
- package/dist/scanning/types.js +5 -0
- package/dist/scanning/types.js.map +1 -0
- package/dist/utils/child-process.d.ts +2 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +4 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/context-classifier.d.ts +11 -0
- package/dist/utils/context-classifier.d.ts.map +1 -0
- package/dist/utils/context-classifier.js +79 -0
- package/dist/utils/context-classifier.js.map +1 -0
- package/dist/utils/exec.d.ts +18 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +51 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/file-filter.d.ts +4 -0
- package/dist/utils/file-filter.d.ts.map +1 -0
- package/dist/utils/file-filter.js +68 -0
- package/dist/utils/file-filter.js.map +1 -0
- package/dist/utils/fs.d.ts +2 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +5 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/post-processor.d.ts +10 -0
- package/dist/utils/post-processor.d.ts.map +1 -0
- package/dist/utils/post-processor.js +183 -0
- package/dist/utils/post-processor.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# SUPABASE SECURITY RULES
|
|
4
|
+
# =============================================================================
|
|
5
|
+
|
|
6
|
+
# ID 34: Service Role Key Exposed in client code
|
|
7
|
+
- id: datahogo-supabase-service-role-client
|
|
8
|
+
patterns:
|
|
9
|
+
- pattern: createClient($URL, $KEY)
|
|
10
|
+
- metavariable-regex:
|
|
11
|
+
metavariable: $KEY
|
|
12
|
+
regex: ".*service_role.*|.*SERVICE_ROLE.*|.*service-role.*"
|
|
13
|
+
message: "Service role key detected in client-side code. Service role keys bypass Row Level Security and should only be used in server-side code with explicit security checks."
|
|
14
|
+
severity: ERROR
|
|
15
|
+
languages: [typescript, javascript]
|
|
16
|
+
metadata:
|
|
17
|
+
datahogo_id: 34
|
|
18
|
+
datahogo_category: "supabase"
|
|
19
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
20
|
+
cwe: "CWE-798"
|
|
21
|
+
|
|
22
|
+
# ID 34: Service Role Key in environment variable access (client-side)
|
|
23
|
+
- id: datahogo-supabase-service-role-env-client
|
|
24
|
+
patterns:
|
|
25
|
+
- pattern-either:
|
|
26
|
+
- pattern: process.env.SUPABASE_SERVICE_ROLE_KEY
|
|
27
|
+
- pattern: process.env.NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY
|
|
28
|
+
- pattern: import.meta.env.VITE_SUPABASE_SERVICE_ROLE_KEY
|
|
29
|
+
message: "Service role key accessed via environment variable in client code. This key should never be exposed to the client and must only be used server-side."
|
|
30
|
+
severity: ERROR
|
|
31
|
+
languages: [typescript, javascript]
|
|
32
|
+
metadata:
|
|
33
|
+
datahogo_id: 34
|
|
34
|
+
datahogo_category: "supabase"
|
|
35
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
36
|
+
cwe: "CWE-798"
|
|
37
|
+
|
|
38
|
+
# ID 31: RLS disabled - createClient without proper context
|
|
39
|
+
- id: datahogo-supabase-no-auth-context
|
|
40
|
+
patterns:
|
|
41
|
+
- pattern: createClient($URL, $KEY, { auth: { persistSession: false } })
|
|
42
|
+
- pattern-not: createClient($URL, $KEY, { auth: { ..., autoRefreshToken: $AUTO } })
|
|
43
|
+
message: "Supabase client created without proper auth context. Ensure Row Level Security (RLS) is enabled on all tables and auth context is properly configured."
|
|
44
|
+
severity: WARNING
|
|
45
|
+
languages: [typescript, javascript]
|
|
46
|
+
metadata:
|
|
47
|
+
datahogo_id: 31
|
|
48
|
+
datahogo_category: "supabase"
|
|
49
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
50
|
+
cwe: "CWE-284"
|
|
51
|
+
|
|
52
|
+
# ID 36: RPC Functions without auth check
|
|
53
|
+
- id: datahogo-supabase-rpc-no-auth
|
|
54
|
+
patterns:
|
|
55
|
+
- pattern: |
|
|
56
|
+
$SUPABASE.rpc($FUNC, $PARAMS)
|
|
57
|
+
- pattern-not-inside: |
|
|
58
|
+
const { data: { user } } = await $SUPABASE.auth.getUser()
|
|
59
|
+
...
|
|
60
|
+
- pattern-not-inside: |
|
|
61
|
+
if (!$USER) { ... }
|
|
62
|
+
...
|
|
63
|
+
message: "Supabase RPC call without auth verification. Always check user authentication before calling RPC functions that perform sensitive operations."
|
|
64
|
+
severity: WARNING
|
|
65
|
+
languages: [typescript, javascript]
|
|
66
|
+
metadata:
|
|
67
|
+
datahogo_id: 36
|
|
68
|
+
datahogo_category: "supabase"
|
|
69
|
+
owasp_ref: "A07:2021 - Identification and Authentication Failures"
|
|
70
|
+
cwe: "CWE-306"
|
|
71
|
+
|
|
72
|
+
# ID 54: No input validation on Supabase queries
|
|
73
|
+
- id: datahogo-supabase-no-input-validation
|
|
74
|
+
patterns:
|
|
75
|
+
- pattern-either:
|
|
76
|
+
- pattern: $SUPABASE.from($TABLE).select().eq($FIELD, $REQ.body.$PARAM)
|
|
77
|
+
- pattern: $SUPABASE.from($TABLE).select().eq($FIELD, $REQ.query.$PARAM)
|
|
78
|
+
- pattern: $SUPABASE.from($TABLE).select().eq($FIELD, $REQ.params.$PARAM)
|
|
79
|
+
- pattern: $SUPABASE.from($TABLE).insert({ ...$REQ.body })
|
|
80
|
+
- pattern: $SUPABASE.from($TABLE).update({ ...$REQ.body })
|
|
81
|
+
- pattern-not-inside: |
|
|
82
|
+
const $VALIDATED = $SCHEMA.parse($REQ.body)
|
|
83
|
+
...
|
|
84
|
+
- pattern-not-inside: |
|
|
85
|
+
if (!$VALIDATION) { ... }
|
|
86
|
+
...
|
|
87
|
+
message: "Direct user input used in Supabase query without validation. Always validate input with Zod or similar schema validation before using in database queries."
|
|
88
|
+
severity: WARNING
|
|
89
|
+
languages: [typescript, javascript]
|
|
90
|
+
metadata:
|
|
91
|
+
datahogo_id: 54
|
|
92
|
+
datahogo_category: "supabase"
|
|
93
|
+
owasp_ref: "A03:2021 - Injection"
|
|
94
|
+
cwe: "CWE-20"
|
|
95
|
+
|
|
96
|
+
# ID 98: Excessive data exposure (select * from Supabase)
|
|
97
|
+
- id: datahogo-supabase-select-all
|
|
98
|
+
patterns:
|
|
99
|
+
- pattern-either:
|
|
100
|
+
- pattern: $SUPABASE.from($TABLE).select("*")
|
|
101
|
+
- pattern: $SUPABASE.from($TABLE).select()
|
|
102
|
+
- pattern-not-inside: |
|
|
103
|
+
async function $FUNC(...$ARGS): Promise<$TYPE> {
|
|
104
|
+
...
|
|
105
|
+
}
|
|
106
|
+
- pattern-inside: |
|
|
107
|
+
export async function $HANDLER($REQ, ...$ARGS) {
|
|
108
|
+
...
|
|
109
|
+
}
|
|
110
|
+
message: "Selecting all columns from Supabase table in API handler. Return only the fields needed to minimize data exposure and improve performance."
|
|
111
|
+
severity: WARNING
|
|
112
|
+
languages: [typescript, javascript]
|
|
113
|
+
metadata:
|
|
114
|
+
datahogo_id: 98
|
|
115
|
+
datahogo_category: "supabase"
|
|
116
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
117
|
+
cwe: "CWE-359"
|
|
118
|
+
|
|
119
|
+
# ID 99: Missing pagination on Supabase queries
|
|
120
|
+
- id: datahogo-supabase-no-pagination
|
|
121
|
+
patterns:
|
|
122
|
+
- pattern: $SUPABASE.from($TABLE).select($FIELDS)
|
|
123
|
+
- pattern-not: $SUPABASE.from($TABLE).select($FIELDS).limit($N)
|
|
124
|
+
- pattern-not: $SUPABASE.from($TABLE).select($FIELDS).range($START, $END)
|
|
125
|
+
- pattern-not: $SUPABASE.from($TABLE).select($FIELDS).single()
|
|
126
|
+
- pattern-not: $SUPABASE.from($TABLE).select($FIELDS).maybeSingle()
|
|
127
|
+
message: "Supabase query without pagination or limit. Add .limit(), .range(), or .single() to prevent excessive data retrieval and potential DoS."
|
|
128
|
+
severity: WARNING
|
|
129
|
+
languages: [typescript, javascript]
|
|
130
|
+
metadata:
|
|
131
|
+
datahogo_id: 99
|
|
132
|
+
datahogo_category: "supabase"
|
|
133
|
+
owasp_ref: "A04:2021 - Insecure Design"
|
|
134
|
+
cwe: "CWE-400"
|
|
135
|
+
|
|
136
|
+
# ID 103: Raw queries in Supabase
|
|
137
|
+
- id: datahogo-supabase-raw-query
|
|
138
|
+
patterns:
|
|
139
|
+
- pattern-either:
|
|
140
|
+
- pattern: $SUPABASE.rpc($FUNC, { query: $SQL })
|
|
141
|
+
- pattern: $SUPABASE.rpc($FUNC, { sql: $SQL })
|
|
142
|
+
- metavariable-pattern:
|
|
143
|
+
metavariable: $SQL
|
|
144
|
+
patterns:
|
|
145
|
+
- pattern-either:
|
|
146
|
+
- pattern: |
|
|
147
|
+
`$...${$VAR}$...`
|
|
148
|
+
- pattern: |
|
|
149
|
+
"$..." + $VAR + "$..."
|
|
150
|
+
message: "Raw SQL query with string interpolation detected in Supabase RPC. Use parameterized queries to prevent SQL injection."
|
|
151
|
+
severity: ERROR
|
|
152
|
+
languages: [typescript, javascript]
|
|
153
|
+
metadata:
|
|
154
|
+
datahogo_id: 103
|
|
155
|
+
datahogo_category: "supabase"
|
|
156
|
+
owasp_ref: "A03:2021 - Injection"
|
|
157
|
+
cwe: "CWE-89"
|
|
158
|
+
|
|
159
|
+
# ID 120: Mass assignment - req.body direct to update
|
|
160
|
+
- id: datahogo-supabase-mass-assignment
|
|
161
|
+
patterns:
|
|
162
|
+
- pattern-either:
|
|
163
|
+
- pattern: $SUPABASE.from($TABLE).update($REQ.body)
|
|
164
|
+
- pattern: $SUPABASE.from($TABLE).update({ ...$REQ.body })
|
|
165
|
+
- pattern: $SUPABASE.from($TABLE).insert($REQ.body)
|
|
166
|
+
- pattern: $SUPABASE.from($TABLE).insert({ ...$REQ.body })
|
|
167
|
+
- pattern: $SUPABASE.from($TABLE).upsert($REQ.body)
|
|
168
|
+
- pattern: $SUPABASE.from($TABLE).upsert({ ...$REQ.body })
|
|
169
|
+
- pattern-not-inside: |
|
|
170
|
+
const { $FIELD1, $FIELD2, ...$REST } = $REQ.body
|
|
171
|
+
...
|
|
172
|
+
message: "Mass assignment vulnerability: request body passed directly to Supabase update/insert. Explicitly whitelist allowed fields to prevent privilege escalation."
|
|
173
|
+
severity: ERROR
|
|
174
|
+
languages: [typescript, javascript]
|
|
175
|
+
metadata:
|
|
176
|
+
datahogo_id: 120
|
|
177
|
+
datahogo_category: "supabase"
|
|
178
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
179
|
+
cwe: "CWE-915"
|
|
180
|
+
|
|
181
|
+
# ID 34: Hardcoded Supabase key
|
|
182
|
+
- id: datahogo-supabase-hardcoded-key
|
|
183
|
+
patterns:
|
|
184
|
+
- pattern: createClient($URL, "$KEY")
|
|
185
|
+
- metavariable-regex:
|
|
186
|
+
metavariable: $KEY
|
|
187
|
+
regex: "^eyJ[a-zA-Z0-9_-]{30,}\\.[a-zA-Z0-9_-]{10,}"
|
|
188
|
+
message: "Hardcoded Supabase key detected. Keys should be loaded from environment variables to avoid exposure in source code."
|
|
189
|
+
severity: ERROR
|
|
190
|
+
languages: [typescript, javascript]
|
|
191
|
+
metadata:
|
|
192
|
+
datahogo_id: 34
|
|
193
|
+
datahogo_category: "supabase"
|
|
194
|
+
owasp_ref: "A02:2021 - Cryptographic Failures"
|
|
195
|
+
cwe: "CWE-798"
|
|
196
|
+
|
|
197
|
+
# =============================================================================
|
|
198
|
+
# FIREBASE SECURITY RULES
|
|
199
|
+
# =============================================================================
|
|
200
|
+
|
|
201
|
+
# ID 43: Firebase API Key in code
|
|
202
|
+
- id: datahogo-firebase-api-key-hardcoded
|
|
203
|
+
patterns:
|
|
204
|
+
- pattern: |
|
|
205
|
+
{
|
|
206
|
+
apiKey: "$KEY",
|
|
207
|
+
...
|
|
208
|
+
}
|
|
209
|
+
- metavariable-regex:
|
|
210
|
+
metavariable: $KEY
|
|
211
|
+
regex: "^AIza[a-zA-Z0-9_-]{35}$"
|
|
212
|
+
message: "Firebase API key hardcoded in source code. Use environment variables to avoid exposure in client bundle."
|
|
213
|
+
severity: WARNING
|
|
214
|
+
languages: [typescript, javascript]
|
|
215
|
+
metadata:
|
|
216
|
+
datahogo_id: 43
|
|
217
|
+
datahogo_category: "firebase"
|
|
218
|
+
owasp_ref: "A02:2021 - Cryptographic Failures"
|
|
219
|
+
cwe: "CWE-798"
|
|
220
|
+
|
|
221
|
+
# ID 44: Firebase Auth without restrictions
|
|
222
|
+
- id: datahogo-firebase-auth-no-email-verification
|
|
223
|
+
patterns:
|
|
224
|
+
- pattern: |
|
|
225
|
+
createUserWithEmailAndPassword($AUTH, $EMAIL, $PASSWORD)
|
|
226
|
+
- pattern-not-inside: |
|
|
227
|
+
const $USER = await createUserWithEmailAndPassword($AUTH, $EMAIL, $PASSWORD)
|
|
228
|
+
await sendEmailVerification($USER.user)
|
|
229
|
+
...
|
|
230
|
+
message: "Firebase user creation without email verification. Implement email verification to prevent fake account creation and ensure user authenticity."
|
|
231
|
+
severity: WARNING
|
|
232
|
+
languages: [typescript, javascript]
|
|
233
|
+
metadata:
|
|
234
|
+
datahogo_id: 44
|
|
235
|
+
datahogo_category: "firebase"
|
|
236
|
+
owasp_ref: "A07:2021 - Identification and Authentication Failures"
|
|
237
|
+
cwe: "CWE-306"
|
|
238
|
+
|
|
239
|
+
# ID 45: Cloud Functions without validation
|
|
240
|
+
- id: datahogo-firebase-function-no-auth
|
|
241
|
+
patterns:
|
|
242
|
+
- pattern: |
|
|
243
|
+
export const $FUNC = onRequest(async ($REQ, $RES) => {
|
|
244
|
+
...
|
|
245
|
+
})
|
|
246
|
+
- pattern-not-inside: |
|
|
247
|
+
export const $FUNC = onRequest(async ($REQ, $RES) => {
|
|
248
|
+
const $TOKEN = $REQ.headers.authorization
|
|
249
|
+
...
|
|
250
|
+
})
|
|
251
|
+
- pattern-not-inside: |
|
|
252
|
+
export const $FUNC = onRequest(async ($REQ, $RES) => {
|
|
253
|
+
if (!$REQ.auth) { ... }
|
|
254
|
+
...
|
|
255
|
+
})
|
|
256
|
+
message: "Firebase Cloud Function without authentication check. Always verify user authentication before processing sensitive operations."
|
|
257
|
+
severity: ERROR
|
|
258
|
+
languages: [typescript, javascript]
|
|
259
|
+
metadata:
|
|
260
|
+
datahogo_id: 45
|
|
261
|
+
datahogo_category: "firebase"
|
|
262
|
+
owasp_ref: "A07:2021 - Identification and Authentication Failures"
|
|
263
|
+
cwe: "CWE-306"
|
|
264
|
+
|
|
265
|
+
# ID 45: Cloud Functions without input validation
|
|
266
|
+
- id: datahogo-firebase-function-no-validation
|
|
267
|
+
patterns:
|
|
268
|
+
- pattern-either:
|
|
269
|
+
- pattern: |
|
|
270
|
+
export const $FUNC = onCall(async ($DATA, $CONTEXT) => {
|
|
271
|
+
...
|
|
272
|
+
$DB.collection($COLL).doc($DATA.$FIELD)
|
|
273
|
+
...
|
|
274
|
+
})
|
|
275
|
+
- pattern: |
|
|
276
|
+
export const $FUNC = onRequest(async ($REQ, $RES) => {
|
|
277
|
+
...
|
|
278
|
+
$DB.collection($COLL).doc($REQ.body.$FIELD)
|
|
279
|
+
...
|
|
280
|
+
})
|
|
281
|
+
- pattern-not-inside: |
|
|
282
|
+
const $VALIDATED = $SCHEMA.parse($DATA)
|
|
283
|
+
...
|
|
284
|
+
- pattern-not-inside: |
|
|
285
|
+
if (typeof $DATA.$FIELD !== "$TYPE") { ... }
|
|
286
|
+
...
|
|
287
|
+
message: "Firebase Cloud Function using request data without validation. Validate all input with schema validation or type checking before use."
|
|
288
|
+
severity: WARNING
|
|
289
|
+
languages: [typescript, javascript]
|
|
290
|
+
metadata:
|
|
291
|
+
datahogo_id: 45
|
|
292
|
+
datahogo_category: "firebase"
|
|
293
|
+
owasp_ref: "A03:2021 - Injection"
|
|
294
|
+
cwe: "CWE-20"
|
|
295
|
+
|
|
296
|
+
# ID 98: Excessive data exposure in Firestore
|
|
297
|
+
- id: datahogo-firestore-get-all-docs
|
|
298
|
+
patterns:
|
|
299
|
+
- pattern: $DB.collection($COLL).get()
|
|
300
|
+
- pattern-not: $DB.collection($COLL).limit($N).get()
|
|
301
|
+
- pattern-not: $DB.collection($COLL).where($FIELD, $OP, $VAL).get()
|
|
302
|
+
message: "Firestore query without filtering or pagination. This can expose excessive data and impact performance. Add .where() or .limit() clauses."
|
|
303
|
+
severity: WARNING
|
|
304
|
+
languages: [typescript, javascript]
|
|
305
|
+
metadata:
|
|
306
|
+
datahogo_id: 98
|
|
307
|
+
datahogo_category: "firebase"
|
|
308
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
309
|
+
cwe: "CWE-359"
|
|
310
|
+
|
|
311
|
+
# ID 54: No input validation on Firestore writes
|
|
312
|
+
- id: datahogo-firestore-no-input-validation
|
|
313
|
+
patterns:
|
|
314
|
+
- pattern-either:
|
|
315
|
+
- pattern: $DB.collection($COLL).add($REQ.body)
|
|
316
|
+
- pattern: $DB.collection($COLL).doc($ID).set($REQ.body)
|
|
317
|
+
- pattern: $DB.collection($COLL).doc($ID).update($REQ.body)
|
|
318
|
+
- pattern-not-inside: |
|
|
319
|
+
const $VALIDATED = $SCHEMA.parse($REQ.body)
|
|
320
|
+
...
|
|
321
|
+
message: "Firestore write operation with unvalidated request data. Always validate input before writing to database to prevent injection and data corruption."
|
|
322
|
+
severity: WARNING
|
|
323
|
+
languages: [typescript, javascript]
|
|
324
|
+
metadata:
|
|
325
|
+
datahogo_id: 54
|
|
326
|
+
datahogo_category: "firebase"
|
|
327
|
+
owasp_ref: "A03:2021 - Injection"
|
|
328
|
+
cwe: "CWE-20"
|
|
329
|
+
|
|
330
|
+
# =============================================================================
|
|
331
|
+
# GENERAL DATABASE SECURITY
|
|
332
|
+
# =============================================================================
|
|
333
|
+
|
|
334
|
+
# ID 103: Prisma raw queries without parameters
|
|
335
|
+
- id: datahogo-prisma-raw-query-injection
|
|
336
|
+
patterns:
|
|
337
|
+
- pattern-either:
|
|
338
|
+
- pattern: $PRISMA.$queryRaw(`$...${$VAR}$...`)
|
|
339
|
+
- pattern: $PRISMA.$executeRaw(`$...${$VAR}$...`)
|
|
340
|
+
- metavariable-pattern:
|
|
341
|
+
metavariable: $VAR
|
|
342
|
+
patterns:
|
|
343
|
+
- pattern-not: Prisma.sql`$...`
|
|
344
|
+
message: "Raw Prisma query with template literal interpolation. Use Prisma.sql tagged template or parameterized queries to prevent SQL injection."
|
|
345
|
+
severity: ERROR
|
|
346
|
+
languages: [typescript, javascript]
|
|
347
|
+
metadata:
|
|
348
|
+
datahogo_id: 103
|
|
349
|
+
datahogo_category: "database"
|
|
350
|
+
owasp_ref: "A03:2021 - Injection"
|
|
351
|
+
cwe: "CWE-89"
|
|
352
|
+
|
|
353
|
+
# ID 103: Sequelize raw queries
|
|
354
|
+
- id: datahogo-sequelize-raw-query-injection
|
|
355
|
+
patterns:
|
|
356
|
+
- pattern-either:
|
|
357
|
+
- pattern: $SEQUELIZE.query(`$...${$VAR}$...`)
|
|
358
|
+
- pattern: $SEQUELIZE.query("$..." + $VAR + "$...")
|
|
359
|
+
- pattern-not: $SEQUELIZE.query($SQL, { replacements: $PARAMS })
|
|
360
|
+
message: "Sequelize raw query with string interpolation. Use parameterized queries with replacements option to prevent SQL injection."
|
|
361
|
+
severity: ERROR
|
|
362
|
+
languages: [typescript, javascript]
|
|
363
|
+
metadata:
|
|
364
|
+
datahogo_id: 103
|
|
365
|
+
datahogo_category: "database"
|
|
366
|
+
owasp_ref: "A03:2021 - Injection"
|
|
367
|
+
cwe: "CWE-89"
|
|
368
|
+
|
|
369
|
+
# ID 120: Mass assignment in Prisma
|
|
370
|
+
- id: datahogo-prisma-mass-assignment
|
|
371
|
+
patterns:
|
|
372
|
+
- pattern-either:
|
|
373
|
+
- pattern: $PRISMA.$MODEL.create({ data: $REQ.body })
|
|
374
|
+
- pattern: $PRISMA.$MODEL.update({ data: $REQ.body, ... })
|
|
375
|
+
- pattern: $PRISMA.$MODEL.upsert({ create: $REQ.body, ... })
|
|
376
|
+
- pattern: $PRISMA.$MODEL.upsert({ update: $REQ.body, ... })
|
|
377
|
+
- pattern-not-inside: |
|
|
378
|
+
const { $FIELD1, $FIELD2, ...$REST } = $REQ.body
|
|
379
|
+
...
|
|
380
|
+
message: "Mass assignment in Prisma: request body passed directly to database operation. Whitelist allowed fields to prevent privilege escalation."
|
|
381
|
+
severity: ERROR
|
|
382
|
+
languages: [typescript, javascript]
|
|
383
|
+
metadata:
|
|
384
|
+
datahogo_id: 120
|
|
385
|
+
datahogo_category: "database"
|
|
386
|
+
owasp_ref: "A01:2021 - Broken Access Control"
|
|
387
|
+
cwe: "CWE-915"
|