@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,380 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
# ID 128: Prototype pollution - deepMerge / lodash.merge without proto filter
|
|
3
|
+
- id: datahogo-prototype-pollution-merge
|
|
4
|
+
patterns:
|
|
5
|
+
- pattern-either:
|
|
6
|
+
- pattern: _.merge($OBJ, $REQ.body)
|
|
7
|
+
- pattern: _.merge($OBJ, $USER_INPUT)
|
|
8
|
+
- pattern: lodash.merge($OBJ, $REQ.body)
|
|
9
|
+
- pattern: deepmerge($OBJ, $REQ.body)
|
|
10
|
+
- pattern: merge($OBJ, $REQ.body)
|
|
11
|
+
message: "Merging user-controlled object without sanitization can cause prototype pollution - filter __proto__ and constructor keys"
|
|
12
|
+
severity: ERROR
|
|
13
|
+
languages: [typescript, javascript]
|
|
14
|
+
metadata:
|
|
15
|
+
datahogo_id: 128
|
|
16
|
+
datahogo_category: "node-security"
|
|
17
|
+
owasp_ref: "A03:2021"
|
|
18
|
+
|
|
19
|
+
- id: datahogo-prototype-pollution-bracket
|
|
20
|
+
patterns:
|
|
21
|
+
- pattern: |
|
|
22
|
+
$OBJ[$REQ.body.$KEY] = $REQ.body.$VALUE
|
|
23
|
+
- pattern-not: |
|
|
24
|
+
if ($KEY !== '__proto__' && $KEY !== 'constructor')
|
|
25
|
+
message: "Dynamic property assignment with user-controlled key can cause prototype pollution"
|
|
26
|
+
severity: ERROR
|
|
27
|
+
languages: [typescript, javascript]
|
|
28
|
+
metadata:
|
|
29
|
+
datahogo_id: 128
|
|
30
|
+
datahogo_category: "node-security"
|
|
31
|
+
owasp_ref: "A03:2021"
|
|
32
|
+
|
|
33
|
+
- id: datahogo-prototype-pollution-dynamic-key
|
|
34
|
+
patterns:
|
|
35
|
+
- pattern: |
|
|
36
|
+
function $FUNC($OBJ, $KEY, $VALUE) {
|
|
37
|
+
...
|
|
38
|
+
$OBJ[$KEY] = $VALUE
|
|
39
|
+
...
|
|
40
|
+
}
|
|
41
|
+
- pattern-not: |
|
|
42
|
+
if ($KEY === '__proto__' || $KEY === 'constructor' || $KEY === 'prototype')
|
|
43
|
+
- pattern-not: |
|
|
44
|
+
if (Object.prototype.hasOwnProperty.call(Object.prototype, $KEY))
|
|
45
|
+
message: "Deep assignment function missing prototype pollution protection - reject __proto__, constructor, and prototype keys"
|
|
46
|
+
severity: WARNING
|
|
47
|
+
languages: [typescript, javascript]
|
|
48
|
+
metadata:
|
|
49
|
+
datahogo_id: 128
|
|
50
|
+
datahogo_category: "node-security"
|
|
51
|
+
owasp_ref: "A03:2021"
|
|
52
|
+
|
|
53
|
+
# ID 129: ReDoS - regex with nested quantifiers
|
|
54
|
+
- id: datahogo-redos-nested-quantifiers
|
|
55
|
+
patterns:
|
|
56
|
+
- pattern-either:
|
|
57
|
+
- pattern: |
|
|
58
|
+
const $RE = /($PATTERN+)+/
|
|
59
|
+
- pattern: |
|
|
60
|
+
const $RE = /($PATTERN*)+/
|
|
61
|
+
- pattern: |
|
|
62
|
+
const $RE = /($PATTERN+)*/
|
|
63
|
+
- pattern: |
|
|
64
|
+
new RegExp("($PATTERN+)+")
|
|
65
|
+
- pattern: |
|
|
66
|
+
new RegExp("($PATTERN*)+")
|
|
67
|
+
message: "Regex with nested quantifiers (e.g. (a+)+) is vulnerable to ReDoS with crafted input - simplify or use a linear-time library"
|
|
68
|
+
severity: WARNING
|
|
69
|
+
languages: [typescript, javascript]
|
|
70
|
+
metadata:
|
|
71
|
+
datahogo_id: 129
|
|
72
|
+
datahogo_category: "node-security"
|
|
73
|
+
owasp_ref: "A05:2021"
|
|
74
|
+
|
|
75
|
+
- id: datahogo-redos-user-input-regex
|
|
76
|
+
patterns:
|
|
77
|
+
- pattern-either:
|
|
78
|
+
- pattern: new RegExp($REQ.body.$FIELD)
|
|
79
|
+
- pattern: new RegExp($REQ.query.$PARAM)
|
|
80
|
+
- pattern: new RegExp($USER_INPUT)
|
|
81
|
+
- pattern-not: |
|
|
82
|
+
safe-regex($INPUT)
|
|
83
|
+
message: "Regex constructed from user input can cause ReDoS or be abused for information disclosure - never allow user-defined regexes"
|
|
84
|
+
severity: ERROR
|
|
85
|
+
languages: [typescript, javascript]
|
|
86
|
+
metadata:
|
|
87
|
+
datahogo_id: 129
|
|
88
|
+
datahogo_category: "node-security"
|
|
89
|
+
owasp_ref: "A05:2021"
|
|
90
|
+
|
|
91
|
+
# ID 130: Insecure randomness
|
|
92
|
+
- id: datahogo-math-random-id
|
|
93
|
+
patterns:
|
|
94
|
+
- pattern-either:
|
|
95
|
+
- pattern: |
|
|
96
|
+
const $ID = Math.random().toString($BASE).slice($N)
|
|
97
|
+
- pattern: |
|
|
98
|
+
const $ID = Math.floor(Math.random() * $N)
|
|
99
|
+
- pattern: |
|
|
100
|
+
id: Math.random()
|
|
101
|
+
- metavariable-regex:
|
|
102
|
+
metavariable: $ID
|
|
103
|
+
regex: .*(id|token|key|secret|session|nonce|code).*
|
|
104
|
+
message: "Math.random() is predictable - use crypto.randomUUID() for IDs or crypto.randomBytes() for tokens"
|
|
105
|
+
severity: ERROR
|
|
106
|
+
languages: [typescript, javascript]
|
|
107
|
+
metadata:
|
|
108
|
+
datahogo_id: 130
|
|
109
|
+
datahogo_category: "node-security"
|
|
110
|
+
owasp_ref: "A02:2021"
|
|
111
|
+
|
|
112
|
+
# ID 131: Service worker without scope
|
|
113
|
+
- id: datahogo-service-worker-no-scope
|
|
114
|
+
patterns:
|
|
115
|
+
- pattern-either:
|
|
116
|
+
- pattern: |
|
|
117
|
+
navigator.serviceWorker.register($FILE)
|
|
118
|
+
- pattern: |
|
|
119
|
+
navigator.serviceWorker.register($FILE, {})
|
|
120
|
+
- pattern-not: |
|
|
121
|
+
navigator.serviceWorker.register($FILE, { scope: $SCOPE })
|
|
122
|
+
message: "Service worker registered without explicit scope - define scope to limit intercepted requests"
|
|
123
|
+
severity: WARNING
|
|
124
|
+
languages: [typescript, javascript]
|
|
125
|
+
metadata:
|
|
126
|
+
datahogo_id: 131
|
|
127
|
+
datahogo_category: "node-security"
|
|
128
|
+
owasp_ref: "A05:2021"
|
|
129
|
+
|
|
130
|
+
# ID 132: Function timeout missing
|
|
131
|
+
- id: datahogo-lambda-no-timeout
|
|
132
|
+
patterns:
|
|
133
|
+
- pattern-either:
|
|
134
|
+
- pattern: |
|
|
135
|
+
export const handler = async (event, context) => {
|
|
136
|
+
...
|
|
137
|
+
}
|
|
138
|
+
- pattern: |
|
|
139
|
+
exports.handler = async (event) => {
|
|
140
|
+
...
|
|
141
|
+
}
|
|
142
|
+
- pattern-not: |
|
|
143
|
+
context.callbackWaitsForEmptyEventLoop = false
|
|
144
|
+
- pattern-not: |
|
|
145
|
+
timeout: $N
|
|
146
|
+
message: "Serverless function without timeout configuration can be abused for resource exhaustion - configure a timeout"
|
|
147
|
+
severity: WARNING
|
|
148
|
+
languages: [typescript, javascript]
|
|
149
|
+
metadata:
|
|
150
|
+
datahogo_id: 132
|
|
151
|
+
datahogo_category: "serverless-cloud"
|
|
152
|
+
owasp_ref: "A05:2021"
|
|
153
|
+
|
|
154
|
+
# ID 134: console.log(process.env) - env vars in logs
|
|
155
|
+
- id: datahogo-console-log-process-env
|
|
156
|
+
patterns:
|
|
157
|
+
- pattern-either:
|
|
158
|
+
- pattern: console.log(process.env)
|
|
159
|
+
- pattern: console.log(..., process.env, ...)
|
|
160
|
+
- pattern: console.info(process.env)
|
|
161
|
+
- pattern: console.error(process.env)
|
|
162
|
+
- pattern: console.log(JSON.stringify(process.env))
|
|
163
|
+
message: "Logging process.env exposes all environment variables including secrets to logs"
|
|
164
|
+
severity: ERROR
|
|
165
|
+
languages: [typescript, javascript]
|
|
166
|
+
metadata:
|
|
167
|
+
datahogo_id: 134
|
|
168
|
+
datahogo_category: "serverless-cloud"
|
|
169
|
+
owasp_ref: "A09:2021"
|
|
170
|
+
|
|
171
|
+
- id: datahogo-console-log-env-var
|
|
172
|
+
patterns:
|
|
173
|
+
- pattern-either:
|
|
174
|
+
- pattern: console.log(..., process.env.$SECRET_VAR, ...)
|
|
175
|
+
- pattern: console.log(`...${ process.env.$SECRET_VAR }...`)
|
|
176
|
+
- metavariable-regex:
|
|
177
|
+
metavariable: $SECRET_VAR
|
|
178
|
+
regex: .*(KEY|SECRET|PASSWORD|TOKEN|PRIVATE|CREDENTIAL|PASS|PWD).*
|
|
179
|
+
message: "Logging secret environment variable exposes sensitive credentials"
|
|
180
|
+
severity: ERROR
|
|
181
|
+
languages: [typescript, javascript]
|
|
182
|
+
metadata:
|
|
183
|
+
datahogo_id: 134
|
|
184
|
+
datahogo_category: "serverless-cloud"
|
|
185
|
+
owasp_ref: "A09:2021"
|
|
186
|
+
|
|
187
|
+
# ID 135: Sensitive files in /tmp
|
|
188
|
+
- id: datahogo-sensitive-tmp-write
|
|
189
|
+
patterns:
|
|
190
|
+
- pattern-either:
|
|
191
|
+
- pattern: |
|
|
192
|
+
fs.writeFile("/tmp/$FILENAME", $DATA, ...)
|
|
193
|
+
- pattern: |
|
|
194
|
+
fs.writeFileSync("/tmp/$FILENAME", $DATA)
|
|
195
|
+
- pattern: |
|
|
196
|
+
fs.writeFile(`/tmp/${$FILENAME}`, ...)
|
|
197
|
+
- metavariable-regex:
|
|
198
|
+
metavariable: $FILENAME
|
|
199
|
+
regex: .*(password|token|key|secret|credential|auth|private).*
|
|
200
|
+
message: "Writing sensitive data to /tmp - files in /tmp may persist across Lambda invocations and be read by other functions"
|
|
201
|
+
severity: WARNING
|
|
202
|
+
languages: [typescript, javascript]
|
|
203
|
+
metadata:
|
|
204
|
+
datahogo_id: 135
|
|
205
|
+
datahogo_category: "serverless-cloud"
|
|
206
|
+
owasp_ref: "A02:2021"
|
|
207
|
+
|
|
208
|
+
# ID 136: Global variables with user data
|
|
209
|
+
- id: datahogo-global-user-data
|
|
210
|
+
patterns:
|
|
211
|
+
- pattern-either:
|
|
212
|
+
- pattern: |
|
|
213
|
+
global.$VAR = $REQ.body
|
|
214
|
+
- pattern: |
|
|
215
|
+
global.$VAR = $REQ.user
|
|
216
|
+
- pattern: |
|
|
217
|
+
global.$VAR = $USER_DATA
|
|
218
|
+
- metavariable-regex:
|
|
219
|
+
metavariable: $VAR
|
|
220
|
+
regex: .*(user|session|request|auth|current).*
|
|
221
|
+
message: "Storing user data in global variables causes data leakage between requests in serverless environments"
|
|
222
|
+
severity: WARNING
|
|
223
|
+
languages: [typescript, javascript]
|
|
224
|
+
metadata:
|
|
225
|
+
datahogo_id: 136
|
|
226
|
+
datahogo_category: "serverless-cloud"
|
|
227
|
+
owasp_ref: "A01:2021"
|
|
228
|
+
|
|
229
|
+
# ID 172: Console.log sensitive data
|
|
230
|
+
- id: datahogo-console-log-sensitive-fields
|
|
231
|
+
patterns:
|
|
232
|
+
- pattern-either:
|
|
233
|
+
- pattern: console.log($OBJ.password)
|
|
234
|
+
- pattern: console.log($OBJ.passwordHash)
|
|
235
|
+
- pattern: console.log($OBJ.creditCard)
|
|
236
|
+
- pattern: console.log($OBJ.ssn)
|
|
237
|
+
- pattern: console.log($OBJ.secret)
|
|
238
|
+
- pattern: console.log(`...${ $OBJ.password }...`)
|
|
239
|
+
- pattern: console.log(`...${ $OBJ.secret }...`)
|
|
240
|
+
message: "Logging sensitive fields (password, secret, credit card) exposes them in logs"
|
|
241
|
+
severity: WARNING
|
|
242
|
+
languages: [typescript, javascript]
|
|
243
|
+
metadata:
|
|
244
|
+
datahogo_id: 172
|
|
245
|
+
datahogo_category: "best-practices"
|
|
246
|
+
owasp_ref: "A09:2021"
|
|
247
|
+
|
|
248
|
+
- id: datahogo-console-log-credentials-object
|
|
249
|
+
patterns:
|
|
250
|
+
- pattern-either:
|
|
251
|
+
- pattern: console.log({ user: $U, password: $P })
|
|
252
|
+
- pattern: console.log({ email: $E, password: $P })
|
|
253
|
+
- pattern: console.log({ ..., password: $P, ... })
|
|
254
|
+
message: "Logging object with password field will expose credentials in logs"
|
|
255
|
+
severity: WARNING
|
|
256
|
+
languages: [typescript, javascript]
|
|
257
|
+
metadata:
|
|
258
|
+
datahogo_id: 172
|
|
259
|
+
datahogo_category: "best-practices"
|
|
260
|
+
owasp_ref: "A09:2021"
|
|
261
|
+
|
|
262
|
+
# ID 173: Stack traces to user
|
|
263
|
+
- id: datahogo-error-stack-to-user
|
|
264
|
+
patterns:
|
|
265
|
+
- pattern-either:
|
|
266
|
+
- pattern: |
|
|
267
|
+
$RESPONSE.json({ ..., stack: $ERROR.stack, ... })
|
|
268
|
+
- pattern: |
|
|
269
|
+
$RESPONSE.json({ error: $ERROR.stack })
|
|
270
|
+
- pattern: |
|
|
271
|
+
$RESPONSE.send($ERROR.stack)
|
|
272
|
+
- pattern: |
|
|
273
|
+
res.status($CODE).json({ ..., stack: err.stack })
|
|
274
|
+
message: "Stack trace returned to API caller exposes internal file paths and implementation details"
|
|
275
|
+
severity: WARNING
|
|
276
|
+
languages: [typescript, javascript]
|
|
277
|
+
metadata:
|
|
278
|
+
datahogo_id: 173
|
|
279
|
+
datahogo_category: "best-practices"
|
|
280
|
+
owasp_ref: "A05:2021"
|
|
281
|
+
|
|
282
|
+
- id: datahogo-error-message-to-user-verbose
|
|
283
|
+
patterns:
|
|
284
|
+
- pattern-either:
|
|
285
|
+
- pattern: |
|
|
286
|
+
$RESPONSE.json({ error: $ERROR.message })
|
|
287
|
+
- pattern: |
|
|
288
|
+
$RESPONSE.status($CODE).json({ message: $ERROR.message })
|
|
289
|
+
- pattern-not: |
|
|
290
|
+
if (process.env.NODE_ENV === "development")
|
|
291
|
+
- pattern-not: |
|
|
292
|
+
if (isDevelopment)
|
|
293
|
+
message: "Raw error messages sent to clients may expose internal details - use generic user-facing messages and log full errors server-side"
|
|
294
|
+
severity: INFO
|
|
295
|
+
languages: [typescript, javascript]
|
|
296
|
+
metadata:
|
|
297
|
+
datahogo_id: 173
|
|
298
|
+
datahogo_category: "best-practices"
|
|
299
|
+
owasp_ref: "A05:2021"
|
|
300
|
+
|
|
301
|
+
# ID 176: PII in logs
|
|
302
|
+
- id: datahogo-pii-in-logs-email
|
|
303
|
+
patterns:
|
|
304
|
+
- pattern-either:
|
|
305
|
+
- pattern: console.log(`...${ $USER.email }...`)
|
|
306
|
+
- pattern: console.log($USER.email)
|
|
307
|
+
- pattern: logger.info({ email: $EMAIL })
|
|
308
|
+
- pattern: logger.info(`user email: ${ $EMAIL }`)
|
|
309
|
+
message: "Logging user email addresses is PII exposure - use user IDs in logs and store emails separately"
|
|
310
|
+
severity: WARNING
|
|
311
|
+
languages: [typescript, javascript]
|
|
312
|
+
metadata:
|
|
313
|
+
datahogo_id: 176
|
|
314
|
+
datahogo_category: "best-practices"
|
|
315
|
+
owasp_ref: "A09:2021"
|
|
316
|
+
|
|
317
|
+
- id: datahogo-pii-in-logs-phone
|
|
318
|
+
patterns:
|
|
319
|
+
- pattern-either:
|
|
320
|
+
- pattern: console.log(`...${ $USER.phone }...`)
|
|
321
|
+
- pattern: console.log(`...${ $USER.phoneNumber }...`)
|
|
322
|
+
- pattern: logger.info({ phone: $PHONE })
|
|
323
|
+
- pattern: logger.info({ phoneNumber: $PHONE })
|
|
324
|
+
message: "Logging phone numbers is PII exposure - reference users by ID in logs"
|
|
325
|
+
severity: WARNING
|
|
326
|
+
languages: [typescript, javascript]
|
|
327
|
+
metadata:
|
|
328
|
+
datahogo_id: 176
|
|
329
|
+
datahogo_category: "best-practices"
|
|
330
|
+
owasp_ref: "A09:2021"
|
|
331
|
+
|
|
332
|
+
# ID 188: Payment data stored locally
|
|
333
|
+
- id: datahogo-payment-data-localstorage
|
|
334
|
+
patterns:
|
|
335
|
+
- pattern-either:
|
|
336
|
+
- pattern: localStorage.setItem($KEY, $CARD_DATA)
|
|
337
|
+
- pattern: sessionStorage.setItem($KEY, $CARD_DATA)
|
|
338
|
+
- metavariable-regex:
|
|
339
|
+
metavariable: $KEY
|
|
340
|
+
regex: .*(card|credit|payment|cvv|pan|billing|stripe).*
|
|
341
|
+
message: "Payment card data must never be stored in localStorage/sessionStorage - violates PCI-DSS compliance"
|
|
342
|
+
severity: CRITICAL
|
|
343
|
+
languages: [typescript, javascript]
|
|
344
|
+
metadata:
|
|
345
|
+
datahogo_id: 188
|
|
346
|
+
datahogo_category: "best-practices"
|
|
347
|
+
owasp_ref: "A02:2021"
|
|
348
|
+
|
|
349
|
+
- id: datahogo-payment-data-in-db
|
|
350
|
+
patterns:
|
|
351
|
+
- pattern-either:
|
|
352
|
+
- pattern: |
|
|
353
|
+
$DB.create({ ..., cardNumber: $NUM, ... })
|
|
354
|
+
- pattern: |
|
|
355
|
+
$DB.create({ ..., cvv: $CVV, ... })
|
|
356
|
+
- pattern: |
|
|
357
|
+
$DB.insert({ ..., card_number: $NUM, ... })
|
|
358
|
+
message: "Storing raw card numbers or CVV in the database violates PCI-DSS - use a payment processor token instead"
|
|
359
|
+
severity: CRITICAL
|
|
360
|
+
languages: [typescript, javascript]
|
|
361
|
+
metadata:
|
|
362
|
+
datahogo_id: 188
|
|
363
|
+
datahogo_category: "best-practices"
|
|
364
|
+
owasp_ref: "A02:2021"
|
|
365
|
+
|
|
366
|
+
# ID 130 Extended: Insecure randomness for session IDs
|
|
367
|
+
- id: datahogo-insecure-session-id
|
|
368
|
+
patterns:
|
|
369
|
+
- pattern-either:
|
|
370
|
+
- pattern: |
|
|
371
|
+
const $SID = Math.random().toString($BASE).slice($N)
|
|
372
|
+
- pattern: |
|
|
373
|
+
sessionId: Math.random().toString($BASE)
|
|
374
|
+
message: "Session IDs must be generated with cryptographically secure randomness - use crypto.randomBytes(32).toString('hex')"
|
|
375
|
+
severity: ERROR
|
|
376
|
+
languages: [typescript, javascript]
|
|
377
|
+
metadata:
|
|
378
|
+
datahogo_id: 130
|
|
379
|
+
datahogo_category: "node-security"
|
|
380
|
+
owasp_ref: "A07:2021"
|