yinzerflow 0.4.4 → 0.5.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.
@@ -0,0 +1,561 @@
1
+ # 📖 Body Parsing Security
2
+
3
+ YinzerFlow provides comprehensive body parsing with built-in security protections against DoS attacks, prototype pollution, and memory exhaustion vulnerabilities. The body parser automatically handles JSON, file uploads, and URL-encoded form data with configurable security limits.
4
+
5
+ For detailed configuration examples and patterns, see [Configuration Guide](../configuration/configuration.md).
6
+
7
+ # ⚙️ Usage
8
+
9
+ ## 🎛️ Settings
10
+
11
+ ### json.maxSize — @default <span style="color: #2ecc71">`262144`</span> (256KB)
12
+
13
+ Maximum JSON request body size in bytes.
14
+
15
+ ```typescript
16
+ const app = new YinzerFlow({
17
+ bodyParser: {
18
+ json: {
19
+ maxSize: 262144 // 256KB limit
20
+ }
21
+ }
22
+ });
23
+ ```
24
+
25
+ <aside>
26
+
27
+ Options: `number` (in bytes)
28
+
29
+ - Minimum: `1024` (1KB)
30
+ - Recommended: `262144` (256KB) for APIs
31
+ - Maximum: Depends on use case, but avoid values over 10MB
32
+ </aside>
33
+
34
+ ### json.maxDepth — @default <span style="color: #2ecc71">`10`</span>
35
+
36
+ Maximum nesting depth to prevent stack overflow attacks.
37
+
38
+ ```typescript
39
+ const app = new YinzerFlow({
40
+ bodyParser: {
41
+ json: {
42
+ maxDepth: 10 // Prevent deep nesting
43
+ }
44
+ }
45
+ });
46
+ ```
47
+
48
+ <aside>
49
+
50
+ Options: `number`
51
+
52
+ - Minimum: `1`
53
+ - Recommended: `10` for most APIs
54
+ - Maximum: `50` (higher values increase stack overflow risk)
55
+ </aside>
56
+
57
+ ### json.allowPrototypeProperties — @default <span style="color: #e74c3c">`false`</span>
58
+
59
+ Allow dangerous prototype properties (⚠️ Security Risk).
60
+
61
+ ```typescript
62
+ const app = new YinzerFlow({
63
+ bodyParser: {
64
+ json: {
65
+ allowPrototypeProperties: false // ✅ Always keep false!
66
+ }
67
+ }
68
+ });
69
+ ```
70
+
71
+ <aside>
72
+
73
+ Options: `boolean`
74
+
75
+ - `false`: Block prototype pollution (default, secure)
76
+ - `true`: Allow prototype properties (⚠️ Security Risk)
77
+ </aside>
78
+
79
+ ### json.maxKeys — @default <span style="color: #2ecc71">`1000`</span>
80
+
81
+ Maximum object keys to prevent memory exhaustion.
82
+
83
+ ```typescript
84
+ const app = new YinzerFlow({
85
+ bodyParser: {
86
+ json: {
87
+ maxKeys: 1000 // Prevent memory exhaustion
88
+ }
89
+ }
90
+ });
91
+ ```
92
+
93
+ <aside>
94
+
95
+ Options: `number`
96
+
97
+ - Minimum: `10`
98
+ - Recommended: `1000` for most APIs
99
+ - Maximum: `10000` (higher values increase memory usage)
100
+ </aside>
101
+
102
+ ### json.maxStringLength — @default <span style="color: #2ecc71">`1048576`</span> (1MB)
103
+
104
+ Maximum length of JSON string values.
105
+
106
+ ```typescript
107
+ const app = new YinzerFlow({
108
+ bodyParser: {
109
+ json: {
110
+ maxStringLength: 1048576 // 1MB string limit
111
+ }
112
+ }
113
+ });
114
+ ```
115
+
116
+ <aside>
117
+
118
+ Options: `number` (in bytes)
119
+
120
+ - Minimum: `100`
121
+ - Recommended: `1048576` (1MB) for most APIs
122
+ - Maximum: `10485760` (10MB) for large text fields
123
+ </aside>
124
+
125
+ ### json.maxArrayLength — @default <span style="color: #2ecc71">`10000`</span>
126
+
127
+ Maximum number of array elements.
128
+
129
+ ```typescript
130
+ const app = new YinzerFlow({
131
+ bodyParser: {
132
+ json: {
133
+ maxArrayLength: 10000 // Prevent large arrays
134
+ }
135
+ }
136
+ });
137
+ ```
138
+
139
+ <aside>
140
+
141
+ Options: `number`
142
+
143
+ - Minimum: `10`
144
+ - Recommended: `10000` for most APIs
145
+ - Maximum: `100000` (higher values increase memory usage)
146
+ </aside>
147
+
148
+ ### fileUploads.maxFileSize — @default <span style="color: #2ecc71">`10485760`</span> (10MB)
149
+
150
+ Maximum size per individual file.
151
+
152
+ ```typescript
153
+ const app = new YinzerFlow({
154
+ bodyParser: {
155
+ fileUploads: {
156
+ maxFileSize: 10485760 // 10MB per file
157
+ }
158
+ }
159
+ });
160
+ ```
161
+
162
+ <aside>
163
+
164
+ Options: `number` (in bytes)
165
+
166
+ - Minimum: `1024` (1KB)
167
+ - Recommended: `10485760` (10MB) for most use cases
168
+ - Maximum: `1073741824` (1GB) for large file handling
169
+ </aside>
170
+
171
+ ### fileUploads.maxTotalSize — @default <span style="color: #2ecc71">`52428800`</span> (50MB)
172
+
173
+ Maximum total size of all files in a single request.
174
+
175
+ ```typescript
176
+ const app = new YinzerFlow({
177
+ bodyParser: {
178
+ fileUploads: {
179
+ maxTotalSize: 52428800 // 50MB total
180
+ }
181
+ }
182
+ });
183
+ ```
184
+
185
+ <aside>
186
+
187
+ Options: `number` (in bytes)
188
+
189
+ - Minimum: `1024` (1KB)
190
+ - Recommended: `52428800` (50MB) for most use cases
191
+ - Maximum: `1073741824` (1GB) for large file uploads
192
+ </aside>
193
+
194
+ ### fileUploads.maxFiles — @default <span style="color: #2ecc71">`10`</span>
195
+
196
+ Maximum number of files per request.
197
+
198
+ ```typescript
199
+ const app = new YinzerFlow({
200
+ bodyParser: {
201
+ fileUploads: {
202
+ maxFiles: 10 // Reasonable file count
203
+ }
204
+ }
205
+ });
206
+ ```
207
+
208
+ <aside>
209
+
210
+ Options: `number`
211
+
212
+ - Minimum: `1`
213
+ - Recommended: `10` for most use cases
214
+ - Maximum: `100` (higher values increase processing time)
215
+ </aside>
216
+
217
+ ### fileUploads.allowedExtensions — @default <span style="color: #2ecc71">`[]`</span>
218
+
219
+ Allowed file extensions (empty array allows all).
220
+
221
+ ```typescript
222
+ const app = new YinzerFlow({
223
+ bodyParser: {
224
+ fileUploads: {
225
+ allowedExtensions: ['.jpg', '.png', '.pdf', '.txt'] // Specific types only
226
+ }
227
+ }
228
+ });
229
+ ```
230
+
231
+ <aside>
232
+
233
+ Options: `string[]`
234
+
235
+ - `[]`: Allow all extensions (default)
236
+ - `['.jpg', '.png', '.pdf']`: Specific file types only
237
+ - `['.txt', '.md', '.json']`: Document types only
238
+ </aside>
239
+
240
+ ### fileUploads.blockedExtensions — @default <span style="color: #2ecc71">`['.exe', '.bat', '.cmd', '.scr', '.pif', '.com']`</span>
241
+
242
+ Blocked file extensions for security.
243
+
244
+ ```typescript
245
+ const app = new YinzerFlow({
246
+ bodyParser: {
247
+ fileUploads: {
248
+ blockedExtensions: ['.exe', '.bat', '.cmd'] // Block dangerous files
249
+ }
250
+ }
251
+ });
252
+ ```
253
+
254
+ <aside>
255
+
256
+ Options: `string[]`
257
+
258
+ - `[]`: No blocked extensions (less secure)
259
+ - `['.exe', '.bat', '.cmd']`: Block executable files (recommended)
260
+ - `['.exe', '.bat', '.cmd', '.scr', '.pif', '.com']`: Comprehensive blocking (default)
261
+ </aside>
262
+
263
+ ### fileUploads.maxFilenameLength — @default <span style="color: #2ecc71">`255`</span>
264
+
265
+ Maximum filename length to prevent path issues.
266
+
267
+ ```typescript
268
+ const app = new YinzerFlow({
269
+ bodyParser: {
270
+ fileUploads: {
271
+ maxFilenameLength: 255 // Standard filename limit
272
+ }
273
+ }
274
+ });
275
+ ```
276
+
277
+ <aside>
278
+
279
+ Options: `number`
280
+
281
+ - Minimum: `10`
282
+ - Recommended: `255` (standard filesystem limit)
283
+ - Maximum: `500` (higher values increase processing overhead)
284
+ </aside>
285
+
286
+ ### urlEncoded.maxSize — @default <span style="color: #2ecc71">`1048576`</span> (1MB)
287
+
288
+ Maximum form data size.
289
+
290
+ ```typescript
291
+ const app = new YinzerFlow({
292
+ bodyParser: {
293
+ urlEncoded: {
294
+ maxSize: 1048576 // 1MB form data limit
295
+ }
296
+ }
297
+ });
298
+ ```
299
+
300
+ <aside>
301
+
302
+ Options: `number` (in bytes)
303
+
304
+ - Minimum: `1024` (1KB)
305
+ - Recommended: `1048576` (1MB) for most forms
306
+ - Maximum: `10485760` (10MB) for large forms
307
+ </aside>
308
+
309
+ ### urlEncoded.maxFields — @default <span style="color: #2ecc71">`1000`</span>
310
+
311
+ Maximum form fields to prevent DoS attacks.
312
+
313
+ ```typescript
314
+ const app = new YinzerFlow({
315
+ bodyParser: {
316
+ urlEncoded: {
317
+ maxFields: 1000 // Prevent DoS through many fields
318
+ }
319
+ }
320
+ });
321
+ ```
322
+
323
+ <aside>
324
+
325
+ Options: `number`
326
+
327
+ - Minimum: `10`
328
+ - Recommended: `1000` for most forms
329
+ - Maximum: `10000` (higher values increase processing time)
330
+ </aside>
331
+
332
+ ### urlEncoded.maxFieldNameLength — @default <span style="color: #2ecc71">`100`</span>
333
+
334
+ Maximum field name length.
335
+
336
+ ```typescript
337
+ const app = new YinzerFlow({
338
+ bodyParser: {
339
+ urlEncoded: {
340
+ maxFieldNameLength: 100 // Reasonable field names
341
+ }
342
+ }
343
+ });
344
+ ```
345
+
346
+ <aside>
347
+
348
+ Options: `number`
349
+
350
+ - Minimum: `5`
351
+ - Recommended: `100` for most forms
352
+ - Maximum: `500` (higher values increase processing overhead)
353
+ </aside>
354
+
355
+ ### urlEncoded.maxFieldLength — @default <span style="color: #2ecc71">`1048576`</span> (1MB)
356
+
357
+ Maximum field value length.
358
+
359
+ ```typescript
360
+ const app = new YinzerFlow({
361
+ bodyParser: {
362
+ urlEncoded: {
363
+ maxFieldLength: 1048576 // 1MB per field
364
+ }
365
+ }
366
+ });
367
+ ```
368
+
369
+ <aside>
370
+
371
+ Options: `number` (in bytes)
372
+
373
+ - Minimum: `100`
374
+ - Recommended: `1048576` (1MB) for most fields
375
+ - Maximum: `10485760` (10MB) for large text fields
376
+ </aside>
377
+
378
+ # ✨ Best Practices
379
+
380
+ - **Set appropriate size limits** based on your use case
381
+ - **Keep `allowPrototypeProperties: false`** for JSON parsing security
382
+ - **Block dangerous file extensions** for file uploads
383
+ - **Use reasonable field limits** to prevent DoS attacks
384
+ - **Test with large payloads** to verify limits work correctly
385
+ - **Monitor memory usage** with high limits
386
+
387
+ # 💻 Examples
388
+
389
+ ### Production API
390
+
391
+ **Use Case:** Secure API with strict body parsing limits
392
+
393
+ **Description:** Production-ready body parsing configuration with conservative limits, blocked dangerous file types, and comprehensive security protections for maximum security.
394
+
395
+ ```typescript
396
+ import { YinzerFlow } from 'yinzerflow';
397
+
398
+ const app = new YinzerFlow({
399
+ port: 3000,
400
+ bodyParser: {
401
+ json: {
402
+ maxSize: 131072, // 128KB - smaller for strict APIs
403
+ maxDepth: 5, // Shallow nesting only
404
+ allowPrototypeProperties: false, // Always keep false!
405
+ maxKeys: 100, // Fewer keys allowed
406
+ maxStringLength: 10240, // 10KB strings max
407
+ maxArrayLength: 100 // Small arrays only
408
+ },
409
+ fileUploads: {
410
+ maxFileSize: 1048576, // 1MB files only
411
+ maxTotalSize: 5242880, // 5MB total
412
+ maxFiles: 3, // Very few files
413
+ allowedExtensions: ['.jpg', '.png', '.pdf'], // Specific types only
414
+ blockedExtensions: ['.exe', '.bat', '.cmd', '.scr', '.pif', '.com'],
415
+ maxFilenameLength: 50 // Short filenames
416
+ },
417
+ urlEncoded: {
418
+ maxSize: 32768, // 32KB forms only
419
+ maxFields: 50, // Fewer fields
420
+ maxFieldNameLength: 50, // Shorter field names
421
+ maxFieldLength: 10240 // 10KB per field
422
+ }
423
+ }
424
+ });
425
+
426
+ app.post('/api/data', ({ request }) => {
427
+ const data = request.body; // Parsed and validated
428
+
429
+ return { success: true, received: data };
430
+ });
431
+
432
+ await app.listen();
433
+ ```
434
+
435
+ ### Dev API
436
+
437
+ **Use Case:** Development server with relaxed body parsing limits
438
+
439
+ **Description:** Development configuration with larger limits, permissive file uploads, and relaxed restrictions for easier testing and debugging.
440
+
441
+ ```typescript
442
+ import { YinzerFlow } from 'yinzerflow';
443
+
444
+ const app = new YinzerFlow({
445
+ port: 3000,
446
+ bodyParser: {
447
+ json: {
448
+ maxSize: 1048576, // 1MB for development
449
+ maxDepth: 20, // Deeper nesting for testing
450
+ allowPrototypeProperties: false, // Still keep secure!
451
+ maxKeys: 5000, // More keys for development
452
+ maxStringLength: 10485760, // 10MB strings for testing
453
+ maxArrayLength: 50000 // Large arrays for testing
454
+ },
455
+ fileUploads: {
456
+ maxFileSize: 104857600, // 100MB for development
457
+ maxTotalSize: 524288000, // 500MB total
458
+ maxFiles: 50, // More files for testing
459
+ allowedExtensions: [], // Allow all extensions in dev
460
+ blockedExtensions: [], // No blocking in dev
461
+ maxFilenameLength: 500 // Longer filenames for testing
462
+ },
463
+ urlEncoded: {
464
+ maxSize: 10485760, // 10MB for development
465
+ maxFields: 10000, // More fields for testing
466
+ maxFieldNameLength: 500, // Longer field names
467
+ maxFieldLength: 10485760 // 10MB per field
468
+ }
469
+ }
470
+ });
471
+
472
+ app.post('/api/test', ({ request }) => {
473
+ const data = request.body;
474
+ return { message: 'Development mode', data };
475
+ });
476
+
477
+ await app.listen();
478
+ ```
479
+
480
+ ## 🚀 Performance Notes
481
+
482
+ - **Early size validation**: Prevents unnecessary processing of oversized requests
483
+ - **Memory limits**: Configurable limits prevent memory exhaustion
484
+ - **Processing overhead**: Minimal impact on request processing time
485
+ - **File upload limits**: Prevent DoS through large file uploads
486
+
487
+ ## 🔒 Security Notes
488
+
489
+ YinzerFlow implements comprehensive security measures to prevent body parsing vulnerabilities:
490
+
491
+ ### 🛡️ JSON DoS Attack Prevention
492
+ - **Problem**: Large or deeply nested JSON can cause memory exhaustion and stack overflow attacks
493
+ - **YinzerFlow Solution**: Configurable size limits, nesting depth limits, key count restrictions, and string/array length limits prevent resource exhaustion
494
+
495
+ ### 🛡️ Prototype Pollution Protection
496
+ - **Problem**: Malicious JSON can pollute JavaScript prototypes using `__proto__`, `constructor`, and `prototype` properties
497
+ - **YinzerFlow Solution**: Blocks dangerous properties by default with `allowPrototypeProperties: false` and validates all object keys
498
+
499
+ ### 🛡️ File Upload Security
500
+ - **Problem**: Malicious file uploads can execute code, consume server resources, or bypass security controls
501
+ - **YinzerFlow Solution**: File type filtering, size limits, filename validation, and extension-based security controls
502
+
503
+ ### 🛡️ Memory Exhaustion Protection
504
+ - **Problem**: Large form data, arrays, or objects can exhaust server memory and cause crashes
505
+ - **YinzerFlow Solution**: Configurable limits on strings, arrays, fields, object keys, and total request sizes
506
+
507
+ ### 🛡️ Request Size Validation
508
+ - **Problem**: Extremely large requests can cause DoS through resource exhaustion
509
+ - **YinzerFlow Solution**: Content-type specific size limits with early validation before full parsing
510
+
511
+ ## 🔧 Troubleshooting
512
+
513
+ ### JSON Parsing Fails
514
+ - **Problem**: Invalid JSON syntax or exceeds limits
515
+ - **Fix**: Check JSON syntax and size limits
516
+
517
+ ```typescript
518
+ // ❌ Wrong - invalid JSON
519
+ const invalidJson = '{ "name": "John", "age": }';
520
+
521
+ // ✅ Correct - valid JSON
522
+ const validJson = '{ "name": "John", "age": 30 }';
523
+ ```
524
+
525
+ ### File Upload Rejected
526
+ - **Problem**: File too large or blocked extension
527
+ - **Fix**: Check file size and extension configuration
528
+
529
+ ```typescript
530
+ // ❌ Wrong - file too large
531
+ fileUploads: { maxFileSize: 1048576 } // 1MB limit
532
+ // Uploading 2MB file
533
+
534
+ // ✅ Correct - increase limit or reduce file size
535
+ fileUploads: { maxFileSize: 2097152 } // 2MB limit
536
+ ```
537
+
538
+ ### Form Data Too Large
539
+ - **Problem**: Form exceeds size or field limits
540
+ - **Fix**: Check form size and field configuration
541
+
542
+ ```typescript
543
+ // ❌ Wrong - too many fields
544
+ urlEncoded: { maxFields: 100 }
545
+ // Form has 150 fields
546
+
547
+ // ✅ Correct - increase limit or reduce fields
548
+ urlEncoded: { maxFields: 200 }
549
+ ```
550
+
551
+ ### Prototype Pollution Warning
552
+ - **Problem**: `allowPrototypeProperties: true` enables dangerous properties
553
+ - **Fix**: Keep this setting false for security
554
+
555
+ ```typescript
556
+ // ❌ Wrong - enables prototype pollution
557
+ json: { allowPrototypeProperties: true }
558
+
559
+ // ✅ Correct - blocks prototype pollution
560
+ json: { allowPrototypeProperties: false }
561
+ ```