@rigour-labs/core 4.3.0 → 4.3.2
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/dist/gates/frontend-secret-exposure.d.ts +27 -0
- package/dist/gates/frontend-secret-exposure.js +174 -0
- package/dist/gates/frontend-secret-exposure.test.d.ts +1 -0
- package/dist/gates/frontend-secret-exposure.test.js +95 -0
- package/dist/gates/runner.js +9 -0
- package/dist/gates/side-effect-analysis.d.ts +67 -0
- package/dist/gates/side-effect-analysis.js +559 -0
- package/dist/gates/side-effect-helpers.d.ts +260 -0
- package/dist/gates/side-effect-helpers.js +1096 -0
- package/dist/gates/side-effect-rules.d.ts +39 -0
- package/dist/gates/side-effect-rules.js +302 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/templates/universal-config.js +42 -0
- package/dist/types/index.d.ts +268 -0
- package/dist/types/index.js +50 -0
- package/package.json +6 -6
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-Effect Analysis Rules
|
|
3
|
+
*
|
|
4
|
+
* Pattern definitions for detecting unbounded side effects that cause
|
|
5
|
+
* real-world consequences: process spawns, resource exhaustion, circular
|
|
6
|
+
* triggers, missing circuit breakers.
|
|
7
|
+
*
|
|
8
|
+
* Each rule has:
|
|
9
|
+
* - regex patterns per language
|
|
10
|
+
* - a check function that verifies context (surrounding lines)
|
|
11
|
+
* - severity and description
|
|
12
|
+
*
|
|
13
|
+
* @since v4.3.0
|
|
14
|
+
*/
|
|
15
|
+
export type SideEffectLang = 'js' | 'ts' | 'py' | 'go' | 'rs' | 'cs' | 'java' | 'rb';
|
|
16
|
+
export interface SideEffectViolation {
|
|
17
|
+
rule: string;
|
|
18
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
19
|
+
file: string;
|
|
20
|
+
line: number;
|
|
21
|
+
match: string;
|
|
22
|
+
description: string;
|
|
23
|
+
hint: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const LANG_MAP: Record<string, SideEffectLang>;
|
|
26
|
+
export declare const FILE_GLOBS: string[];
|
|
27
|
+
export declare const TIMER_CREATE_PATTERNS: Record<string, RegExp[]>;
|
|
28
|
+
export declare const TIMER_CLEANUP_PATTERNS: Record<string, RegExp[]>;
|
|
29
|
+
export declare const PROCESS_SPAWN_PATTERNS: Record<string, RegExp[]>;
|
|
30
|
+
export declare const PROCESS_EXIT_PATTERNS: Record<string, RegExp[]>;
|
|
31
|
+
export declare const UNBOUNDED_LOOP_PATTERNS: Record<string, RegExp[]>;
|
|
32
|
+
export declare const IO_PATTERNS: Record<string, RegExp[]>;
|
|
33
|
+
export declare const RETRY_PATTERNS: Record<string, RegExp[]>;
|
|
34
|
+
export declare const MAX_RETRY_INDICATORS: RegExp[];
|
|
35
|
+
export declare const WATCHER_PATTERNS: Record<string, RegExp[]>;
|
|
36
|
+
export declare const WRITE_PATTERNS: Record<string, RegExp[]>;
|
|
37
|
+
export declare const RESOURCE_OPEN_PATTERNS: Record<string, RegExp[]>;
|
|
38
|
+
export declare const RESOURCE_CLOSE_PATTERNS: Record<string, RegExp[]>;
|
|
39
|
+
export declare const AUTO_RESTART_PATTERNS: Record<string, RegExp[]>;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-Effect Analysis Rules
|
|
3
|
+
*
|
|
4
|
+
* Pattern definitions for detecting unbounded side effects that cause
|
|
5
|
+
* real-world consequences: process spawns, resource exhaustion, circular
|
|
6
|
+
* triggers, missing circuit breakers.
|
|
7
|
+
*
|
|
8
|
+
* Each rule has:
|
|
9
|
+
* - regex patterns per language
|
|
10
|
+
* - a check function that verifies context (surrounding lines)
|
|
11
|
+
* - severity and description
|
|
12
|
+
*
|
|
13
|
+
* @since v4.3.0
|
|
14
|
+
*/
|
|
15
|
+
// ── Language detection ──
|
|
16
|
+
export const LANG_MAP = {
|
|
17
|
+
'.ts': 'ts', '.tsx': 'ts', '.mts': 'ts',
|
|
18
|
+
'.js': 'js', '.jsx': 'js', '.mjs': 'js', '.cjs': 'js',
|
|
19
|
+
'.py': 'py',
|
|
20
|
+
'.go': 'go',
|
|
21
|
+
'.rs': 'rs',
|
|
22
|
+
'.cs': 'cs',
|
|
23
|
+
'.java': 'java',
|
|
24
|
+
'.rb': 'rb',
|
|
25
|
+
};
|
|
26
|
+
export const FILE_GLOBS = [
|
|
27
|
+
'**/*.{ts,tsx,mts,js,jsx,mjs,cjs}',
|
|
28
|
+
'**/*.py',
|
|
29
|
+
'**/*.go',
|
|
30
|
+
'**/*.rs',
|
|
31
|
+
'**/*.cs',
|
|
32
|
+
'**/*.java',
|
|
33
|
+
'**/*.rb',
|
|
34
|
+
];
|
|
35
|
+
// ── Timer patterns (setInterval/setTimeout without cleanup) ──
|
|
36
|
+
export const TIMER_CREATE_PATTERNS = {
|
|
37
|
+
js: [
|
|
38
|
+
/\bsetInterval\s*\(/,
|
|
39
|
+
/\bsetTimeout\s*\(/,
|
|
40
|
+
],
|
|
41
|
+
ts: [
|
|
42
|
+
/\bsetInterval\s*\(/,
|
|
43
|
+
/\bsetTimeout\s*\(/,
|
|
44
|
+
],
|
|
45
|
+
py: [
|
|
46
|
+
/\bscheduler\.enter\s*\(/,
|
|
47
|
+
/\bTimer\s*\(/,
|
|
48
|
+
/\bschedule\.every\b/,
|
|
49
|
+
],
|
|
50
|
+
go: [
|
|
51
|
+
/\btime\.NewTicker\s*\(/,
|
|
52
|
+
/\btime\.Tick\s*\(/,
|
|
53
|
+
],
|
|
54
|
+
java: [
|
|
55
|
+
/\bScheduledExecutorService\b/,
|
|
56
|
+
/\bTimer\(\)\.schedule\b/,
|
|
57
|
+
/\bTimer\(\)\.scheduleAtFixedRate\b/,
|
|
58
|
+
],
|
|
59
|
+
rs: [],
|
|
60
|
+
cs: [
|
|
61
|
+
/\bnew\s+Timer\s*\(/,
|
|
62
|
+
/\bSetInterval\s*\(/,
|
|
63
|
+
],
|
|
64
|
+
rb: [],
|
|
65
|
+
};
|
|
66
|
+
export const TIMER_CLEANUP_PATTERNS = {
|
|
67
|
+
js: [/\bclearInterval\s*\(/, /\bclearTimeout\s*\(/],
|
|
68
|
+
ts: [/\bclearInterval\s*\(/, /\bclearTimeout\s*\(/],
|
|
69
|
+
py: [/\.cancel\s*\(/],
|
|
70
|
+
go: [/\.Stop\s*\(/],
|
|
71
|
+
java: [/\.shutdown\s*\(/, /\.cancel\s*\(/],
|
|
72
|
+
rs: [],
|
|
73
|
+
cs: [/\.Dispose\s*\(/, /\.Stop\s*\(/],
|
|
74
|
+
rb: [],
|
|
75
|
+
};
|
|
76
|
+
// ── Process spawn patterns ──
|
|
77
|
+
export const PROCESS_SPAWN_PATTERNS = {
|
|
78
|
+
js: [
|
|
79
|
+
/\bchild_process\.\w+\s*\(/,
|
|
80
|
+
/\bspawn\s*\(/,
|
|
81
|
+
/\bexec\s*\(/,
|
|
82
|
+
/\bexecFile\s*\(/,
|
|
83
|
+
/\bfork\s*\(/,
|
|
84
|
+
/\bexeca\s*\(/,
|
|
85
|
+
],
|
|
86
|
+
ts: [
|
|
87
|
+
/\bchild_process\.\w+\s*\(/,
|
|
88
|
+
/\bspawn\s*\(/,
|
|
89
|
+
/\bexec\s*\(/,
|
|
90
|
+
/\bexecFile\s*\(/,
|
|
91
|
+
/\bfork\s*\(/,
|
|
92
|
+
/\bexeca\s*\(/,
|
|
93
|
+
],
|
|
94
|
+
py: [
|
|
95
|
+
/\bsubprocess\.\w+\s*\(/,
|
|
96
|
+
/\bPopen\s*\(/,
|
|
97
|
+
/\bos\.system\s*\(/,
|
|
98
|
+
/\bos\.exec\w*\s*\(/,
|
|
99
|
+
/\bos\.spawn\w*\s*\(/,
|
|
100
|
+
],
|
|
101
|
+
go: [
|
|
102
|
+
/\bexec\.Command\s*\(/,
|
|
103
|
+
/\bos\/exec\b/,
|
|
104
|
+
/\bcmd\.Start\s*\(/,
|
|
105
|
+
/\bcmd\.Run\s*\(/,
|
|
106
|
+
],
|
|
107
|
+
java: [
|
|
108
|
+
/\bProcessBuilder\b/,
|
|
109
|
+
/\bRuntime\.getRuntime\(\)\.exec\s*\(/,
|
|
110
|
+
],
|
|
111
|
+
rs: [
|
|
112
|
+
/\bCommand::new\s*\(/,
|
|
113
|
+
/\bstd::process::Command\b/,
|
|
114
|
+
],
|
|
115
|
+
cs: [
|
|
116
|
+
/\bProcess\.Start\s*\(/,
|
|
117
|
+
/\bnew\s+ProcessStartInfo\b/,
|
|
118
|
+
],
|
|
119
|
+
rb: [
|
|
120
|
+
/\bsystem\s*\(/,
|
|
121
|
+
/\bspawn\s*\(/,
|
|
122
|
+
/\b`[^`]+`/,
|
|
123
|
+
/\bIO\.popen\s*\(/,
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
export const PROCESS_EXIT_PATTERNS = {
|
|
127
|
+
js: [/\.on\s*\(\s*['"](?:exit|close)['"]/, /\.kill\s*\(/, /\.disconnect\s*\(/],
|
|
128
|
+
ts: [/\.on\s*\(\s*['"](?:exit|close)['"]/, /\.kill\s*\(/, /\.disconnect\s*\(/],
|
|
129
|
+
py: [/\.wait\s*\(/, /\.terminate\s*\(/, /\.kill\s*\(/, /\.communicate\s*\(/],
|
|
130
|
+
go: [/\.Wait\s*\(/, /cmd\.Process\.Kill\s*\(/],
|
|
131
|
+
java: [/\.waitFor\s*\(/, /\.destroy\s*\(/, /\.destroyForcibly\s*\(/],
|
|
132
|
+
rs: [/\.wait\s*\(/, /\.kill\s*\(/],
|
|
133
|
+
cs: [/\.WaitForExit\s*\(/, /\.Kill\s*\(/, /\.Close\s*\(/],
|
|
134
|
+
rb: [/Process\.wait\b/, /Process\.kill\b/],
|
|
135
|
+
};
|
|
136
|
+
// ── Unbounded loop patterns ──
|
|
137
|
+
export const UNBOUNDED_LOOP_PATTERNS = {
|
|
138
|
+
js: [/\bwhile\s*\(\s*true\s*\)/, /\bwhile\s*\(\s*1\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
139
|
+
ts: [/\bwhile\s*\(\s*true\s*\)/, /\bwhile\s*\(\s*1\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
140
|
+
py: [/\bwhile\s+True\s*:/, /\bwhile\s+1\s*:/],
|
|
141
|
+
go: [/\bfor\s*\{/, /\bfor\s+\{/], // bare `for {` in Go = infinite loop
|
|
142
|
+
java: [/\bwhile\s*\(\s*true\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
143
|
+
rs: [/\bloop\s*\{/],
|
|
144
|
+
cs: [/\bwhile\s*\(\s*true\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
145
|
+
rb: [/\bloop\s+do\b/, /\bwhile\s+true\b/],
|
|
146
|
+
};
|
|
147
|
+
// I/O operations inside loops that indicate resource impact
|
|
148
|
+
export const IO_PATTERNS = {
|
|
149
|
+
js: [
|
|
150
|
+
/\bfs\.\w+/, /\bfetch\s*\(/, /\baxios\.\w+/, /\bhttp\.\w+/,
|
|
151
|
+
/\.write\s*\(/, /\.send\s*\(/, /\bchild_process\./,
|
|
152
|
+
/\bconsole\.\w+/, /\bprocess\.stdout/,
|
|
153
|
+
],
|
|
154
|
+
ts: [
|
|
155
|
+
/\bfs\.\w+/, /\bfetch\s*\(/, /\baxios\.\w+/, /\bhttp\.\w+/,
|
|
156
|
+
/\.write\s*\(/, /\.send\s*\(/, /\bchild_process\./,
|
|
157
|
+
],
|
|
158
|
+
py: [
|
|
159
|
+
/\bopen\s*\(/, /\brequests\.\w+/, /\burllib\.\w+/,
|
|
160
|
+
/\bsubprocess\./, /\bos\.\w+/, /\bsocket\.\w+/,
|
|
161
|
+
/\.write\s*\(/, /\bprint\s*\(/,
|
|
162
|
+
],
|
|
163
|
+
go: [
|
|
164
|
+
/\bos\.\w+/, /\bnet\.\w+/, /\bhttp\.\w+/,
|
|
165
|
+
/\bio\.\w+/, /\bfmt\.Fprint/, /\bioutil\.\w+/,
|
|
166
|
+
/\bexec\.Command/,
|
|
167
|
+
],
|
|
168
|
+
java: [
|
|
169
|
+
/\bnew\s+File\w*\(/, /\bHttpClient\b/, /\bSocket\b/,
|
|
170
|
+
/\.write\s*\(/, /\bRuntime\.getRuntime\(\)/,
|
|
171
|
+
],
|
|
172
|
+
rs: [
|
|
173
|
+
/\bstd::fs::/, /\bstd::net::/, /\bstd::process::/,
|
|
174
|
+
/\.write\s*\(/, /\btokio::\w+/,
|
|
175
|
+
],
|
|
176
|
+
cs: [
|
|
177
|
+
/\bFile\.\w+/, /\bHttpClient\b/, /\bProcess\.Start/,
|
|
178
|
+
/\.Write\s*\(/, /\bSocket\b/,
|
|
179
|
+
],
|
|
180
|
+
rb: [
|
|
181
|
+
/\bFile\.\w+/, /\bNet::HTTP\b/, /\bIO\.\w+/,
|
|
182
|
+
/\.write\s*\(/, /\bsystem\s*\(/,
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
// ── Retry without limit patterns ──
|
|
186
|
+
export const RETRY_PATTERNS = {
|
|
187
|
+
js: [/\bcatch\s*\([^)]*\)\s*\{/, /\.catch\s*\(/],
|
|
188
|
+
ts: [/\bcatch\s*\([^)]*\)\s*\{/, /\.catch\s*\(/],
|
|
189
|
+
py: [/\bexcept\s+\w+/, /\bexcept\s*:/],
|
|
190
|
+
go: [/\bif\s+err\s*!=\s*nil\b/],
|
|
191
|
+
java: [/\bcatch\s*\(\w+\s+\w+\)/, /\bcatch\s*\(\s*Exception\b/],
|
|
192
|
+
rs: [/\.unwrap_or_else\s*\(/, /\bif\s+let\s+Err\b/],
|
|
193
|
+
cs: [/\bcatch\s*\(\w+\b/, /\bcatch\s*\{/],
|
|
194
|
+
rb: [/\brescue\b/],
|
|
195
|
+
};
|
|
196
|
+
export const MAX_RETRY_INDICATORS = [
|
|
197
|
+
/max.?retries?/i,
|
|
198
|
+
/retry.?count/i,
|
|
199
|
+
/retry.?limit/i,
|
|
200
|
+
/attempt/i,
|
|
201
|
+
/retries?\s*[<>=!]+\s*\d+/,
|
|
202
|
+
/count\s*[<>=!]+\s*\d+/,
|
|
203
|
+
/MAX_/,
|
|
204
|
+
/backoff/i,
|
|
205
|
+
/circuit.?breaker/i,
|
|
206
|
+
];
|
|
207
|
+
// ── File watcher patterns (circular trigger detection) ──
|
|
208
|
+
export const WATCHER_PATTERNS = {
|
|
209
|
+
js: [
|
|
210
|
+
/\bfs\.watch\s*\(/, /\bfs\.watchFile\s*\(/,
|
|
211
|
+
/\bchokidar\.watch\s*\(/, /\bnodemon\b/,
|
|
212
|
+
/\bnew\s+FSWatcher\b/,
|
|
213
|
+
],
|
|
214
|
+
ts: [
|
|
215
|
+
/\bfs\.watch\s*\(/, /\bfs\.watchFile\s*\(/,
|
|
216
|
+
/\bchokidar\.watch\s*\(/,
|
|
217
|
+
/\bnew\s+FSWatcher\b/,
|
|
218
|
+
],
|
|
219
|
+
py: [
|
|
220
|
+
/\bwatchdog\b/, /\bObserver\s*\(/,
|
|
221
|
+
/\binotify\b/, /\bwatchfiles\b/,
|
|
222
|
+
],
|
|
223
|
+
go: [
|
|
224
|
+
/\bfsnotify\.\w+/, /\bNewWatcher\s*\(/,
|
|
225
|
+
],
|
|
226
|
+
java: [
|
|
227
|
+
/\bWatchService\b/, /\bWatchKey\b/,
|
|
228
|
+
],
|
|
229
|
+
rs: [
|
|
230
|
+
/\bnotify::/, /\bRecommendedWatcher\b/,
|
|
231
|
+
],
|
|
232
|
+
cs: [
|
|
233
|
+
/\bFileSystemWatcher\b/, /\bnew\s+FileSystemWatcher\b/,
|
|
234
|
+
],
|
|
235
|
+
rb: [
|
|
236
|
+
/\bListen\.\w+/, /\brb-inotify\b/,
|
|
237
|
+
],
|
|
238
|
+
};
|
|
239
|
+
export const WRITE_PATTERNS = {
|
|
240
|
+
js: [/\bfs\.writeFile/, /\bfs\.appendFile/, /\bfs\.createWriteStream/, /\.write\s*\(/],
|
|
241
|
+
ts: [/\bfs\.writeFile/, /\bfs\.appendFile/, /\bfs\.createWriteStream/, /\.write\s*\(/],
|
|
242
|
+
py: [/\bopen\s*\([^)]*['"][wa]['"]/, /\.write\s*\(/, /\bshutil\.\w+/],
|
|
243
|
+
go: [/\bos\.WriteFile/, /\bos\.Create/, /\bio\.WriteString/, /\.Write\s*\(/],
|
|
244
|
+
java: [/\bFileWriter\b/, /\bBufferedWriter\b/, /\.write\s*\(/],
|
|
245
|
+
rs: [/\bfs::write/, /\bFile::create/, /\.write_all\s*\(/],
|
|
246
|
+
cs: [/\bFile\.Write/, /\bStreamWriter\b/, /\.Write\s*\(/],
|
|
247
|
+
rb: [/\bFile\.write/, /\bFile\.open\s*\([^)]*['"]w['"]/, /\.write\s*\(/],
|
|
248
|
+
};
|
|
249
|
+
// ── Resource lifecycle patterns (open without close) ──
|
|
250
|
+
export const RESOURCE_OPEN_PATTERNS = {
|
|
251
|
+
js: [/\bfs\.open\s*\(/, /\bfs\.createReadStream\s*\(/, /\bfs\.createWriteStream\s*\(/],
|
|
252
|
+
ts: [/\bfs\.open\s*\(/, /\bfs\.createReadStream\s*\(/, /\bfs\.createWriteStream\s*\(/],
|
|
253
|
+
py: [/\bopen\s*\(/],
|
|
254
|
+
go: [/\bos\.Open\s*\(/, /\bos\.Create\s*\(/, /\bos\.OpenFile\s*\(/],
|
|
255
|
+
java: [/\bnew\s+FileInputStream\b/, /\bnew\s+FileOutputStream\b/, /\bnew\s+BufferedReader\b/],
|
|
256
|
+
rs: [/\bFile::open\s*\(/, /\bFile::create\s*\(/],
|
|
257
|
+
cs: [/\bFile\.Open\s*\(/, /\bnew\s+FileStream\b/, /\bnew\s+StreamReader\b/],
|
|
258
|
+
rb: [/\bFile\.open\s*\(/],
|
|
259
|
+
};
|
|
260
|
+
export const RESOURCE_CLOSE_PATTERNS = {
|
|
261
|
+
js: [/\.close\s*\(/, /\.destroy\s*\(/, /\.end\s*\(/],
|
|
262
|
+
ts: [/\.close\s*\(/, /\.destroy\s*\(/, /\.end\s*\(/],
|
|
263
|
+
py: [/\.close\s*\(/, /\bwith\s+open\b/], // `with` auto-closes
|
|
264
|
+
go: [/\.Close\s*\(/, /\bdefer\b/], // defer auto-closes
|
|
265
|
+
java: [/\.close\s*\(/, /\btry\s*\(/], // try-with-resources
|
|
266
|
+
rs: [/\bdrop\s*\(/, /\}$/], // Rust auto-drops
|
|
267
|
+
cs: [/\.Close\s*\(/, /\.Dispose\s*\(/, /\busing\s*\(/], // using auto-disposes
|
|
268
|
+
rb: [/\.close\b/, /\bFile\.open\s*\([^)]*\)\s*do\b/], // block form auto-closes
|
|
269
|
+
};
|
|
270
|
+
// ── Auto-restart / self-respawn patterns ──
|
|
271
|
+
export const AUTO_RESTART_PATTERNS = {
|
|
272
|
+
js: [
|
|
273
|
+
/process\.on\s*\(\s*['"](?:exit|uncaughtException|SIGTERM)['"]\s*,\s*(?:function|\(|=>).*(?:spawn|exec|fork)/,
|
|
274
|
+
/process\.on\s*\(\s*['"]exit['"]/,
|
|
275
|
+
],
|
|
276
|
+
ts: [
|
|
277
|
+
/process\.on\s*\(\s*['"](?:exit|uncaughtException|SIGTERM)['"]\s*,\s*(?:function|\(|=>).*(?:spawn|exec|fork)/,
|
|
278
|
+
/process\.on\s*\(\s*['"]exit['"]/,
|
|
279
|
+
],
|
|
280
|
+
py: [
|
|
281
|
+
/\batexit\.register\s*\(/,
|
|
282
|
+
/\bsignal\.signal\s*\(\s*signal\.SIG\w+\s*,/,
|
|
283
|
+
],
|
|
284
|
+
go: [
|
|
285
|
+
/\bsignal\.Notify\s*\(/,
|
|
286
|
+
/\bos\.Exit\s*\(/,
|
|
287
|
+
],
|
|
288
|
+
java: [
|
|
289
|
+
/\bRuntime\.getRuntime\(\)\.addShutdownHook\b/,
|
|
290
|
+
],
|
|
291
|
+
rs: [
|
|
292
|
+
/\bctrlc::set_handler\b/,
|
|
293
|
+
/\bsignal::ctrl_c\b/,
|
|
294
|
+
],
|
|
295
|
+
cs: [
|
|
296
|
+
/\bAppDomain\.CurrentDomain\.ProcessExit\b/,
|
|
297
|
+
],
|
|
298
|
+
rb: [
|
|
299
|
+
/\bat_exit\b/,
|
|
300
|
+
/\btrap\s*\(/,
|
|
301
|
+
],
|
|
302
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from './templates/index.js';
|
|
|
6
6
|
export * from './types/fix-packet.js';
|
|
7
7
|
export { Gate, GateContext } from './gates/base.js';
|
|
8
8
|
export { RetryLoopBreakerGate } from './gates/retry-loop-breaker.js';
|
|
9
|
+
export { SideEffectAnalysisGate } from './gates/side-effect-analysis.js';
|
|
10
|
+
export { FrontendSecretExposureGate } from './gates/frontend-secret-exposure.js';
|
|
9
11
|
export * from './utils/logger.js';
|
|
10
12
|
export * from './services/score-history.js';
|
|
11
13
|
export * from './hooks/index.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export * from './templates/index.js';
|
|
|
6
6
|
export * from './types/fix-packet.js';
|
|
7
7
|
export { Gate } from './gates/base.js';
|
|
8
8
|
export { RetryLoopBreakerGate } from './gates/retry-loop-breaker.js';
|
|
9
|
+
export { SideEffectAnalysisGate } from './gates/side-effect-analysis.js';
|
|
10
|
+
export { FrontendSecretExposureGate } from './gates/frontend-secret-exposure.js';
|
|
9
11
|
export * from './utils/logger.js';
|
|
10
12
|
export * from './services/score-history.js';
|
|
11
13
|
export * from './hooks/index.js';
|
|
@@ -72,6 +72,36 @@ export const UNIVERSAL_CONFIG = {
|
|
|
72
72
|
command_injection: true,
|
|
73
73
|
block_on_severity: 'high',
|
|
74
74
|
},
|
|
75
|
+
frontend_secret_exposure: {
|
|
76
|
+
enabled: true,
|
|
77
|
+
block_on_severity: 'high',
|
|
78
|
+
check_process_env: true,
|
|
79
|
+
check_import_meta_env: true,
|
|
80
|
+
secret_env_name_patterns: [
|
|
81
|
+
'(?:^|_)(?:secret|private)(?:_|$)',
|
|
82
|
+
'(?:^|_)(?:token|api[_-]?key|access[_-]?key|client[_-]?secret|signing|webhook)(?:_|$)',
|
|
83
|
+
'(?:^|_)(?:db[_-]?url|database[_-]?url|connection[_-]?string)(?:_|$)',
|
|
84
|
+
],
|
|
85
|
+
safe_public_prefixes: ['NEXT_PUBLIC_', 'VITE_', 'PUBLIC_', 'NUXT_PUBLIC_', 'REACT_APP_'],
|
|
86
|
+
frontend_path_patterns: [
|
|
87
|
+
'(^|/)pages/(?!api/)',
|
|
88
|
+
'(^|/)components/',
|
|
89
|
+
'(^|/)src/components/',
|
|
90
|
+
'(^|/)src/views/',
|
|
91
|
+
'(^|/)src/app/',
|
|
92
|
+
'(^|/)app/(?!api/)',
|
|
93
|
+
'(^|/)views/',
|
|
94
|
+
'(^|/)public/',
|
|
95
|
+
],
|
|
96
|
+
server_path_patterns: [
|
|
97
|
+
'(^|/)pages/api/',
|
|
98
|
+
'(^|/)src/pages/api/',
|
|
99
|
+
'(^|/)app/api/',
|
|
100
|
+
'(^|/)src/app/api/',
|
|
101
|
+
'\\.server\\.(?:ts|tsx|js|jsx|mjs|cjs)$',
|
|
102
|
+
],
|
|
103
|
+
allowlist_env_names: [],
|
|
104
|
+
},
|
|
75
105
|
adaptive: {
|
|
76
106
|
enabled: false,
|
|
77
107
|
base_coverage_threshold: 80,
|
|
@@ -187,6 +217,18 @@ export const UNIVERSAL_CONFIG = {
|
|
|
187
217
|
ignore_patterns: [],
|
|
188
218
|
audit_log: true,
|
|
189
219
|
},
|
|
220
|
+
side_effect_analysis: {
|
|
221
|
+
enabled: true,
|
|
222
|
+
check_unbounded_timers: true,
|
|
223
|
+
check_unbounded_loops: true,
|
|
224
|
+
check_process_lifecycle: true,
|
|
225
|
+
check_recursive_depth: true,
|
|
226
|
+
check_resource_lifecycle: true,
|
|
227
|
+
check_retry_without_limit: true,
|
|
228
|
+
check_circular_triggers: true,
|
|
229
|
+
check_auto_restart: true,
|
|
230
|
+
ignore_patterns: [],
|
|
231
|
+
},
|
|
190
232
|
deep: {
|
|
191
233
|
enabled: false,
|
|
192
234
|
pro: false,
|