securenow 5.8.0 → 5.8.1

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.
@@ -362,6 +362,14 @@ OTEL_EXPORTER_OTLP_HEADERS="x-api-key=KEY"
362
362
  SECURENOW_APPID=my-app # Your app name
363
363
  OTEL_SERVICE_NAME=my-app # Alternative
364
364
 
365
+ # Request Body Capture
366
+ SECURENOW_CAPTURE_BODY=1 # Capture JSON/form/GraphQL request bodies
367
+ SECURENOW_MAX_BODY_SIZE=10240 # Max body size in bytes (default: 10KB)
368
+ SECURENOW_SENSITIVE_FIELDS="field1,field2" # Additional fields to redact
369
+
370
+ # Multipart Body Capture (v5.8.0+)
371
+ SECURENOW_CAPTURE_MULTIPART=1 # Capture multipart field values & file metadata (streaming)
372
+
365
373
  # Debugging
366
374
  OTEL_LOG_LEVEL=debug # Enable debug output
367
375
  ```
package/NPM_README.md CHANGED
@@ -903,6 +903,7 @@ export default defineNuxtConfig({
903
903
  | `SECURENOW_CAPTURE_BODY` | Enable request body capture in traces. Set to `1` to enable. | `0` |
904
904
  | `SECURENOW_MAX_BODY_SIZE` | Maximum body size to capture in bytes. Bodies larger than this are truncated. | `10240` (10KB) |
905
905
  | `SECURENOW_SENSITIVE_FIELDS` | Comma-separated list of additional field names to redact. | - |
906
+ | `SECURENOW_CAPTURE_MULTIPART` | Enable multipart/form-data capture. Streams through the request to extract text field values and file metadata (name, filename, content-type, size) without buffering file content. Set to `1` to enable. | `0` |
906
907
 
907
908
  **Default sensitive fields (auto-redacted):** `password`, `passwd`, `pwd`, `secret`, `token`, `api_key`, `apikey`, `access_token`, `auth`, `credentials`, `mysql_pwd`, `stripeToken`, `card`, `cardnumber`, `ccv`, `cvc`, `cvv`, `ssn`, `pin`
908
909
 
@@ -1018,8 +1019,28 @@ export SECURENOW_MAX_BODY_SIZE=10240 # 10KB (optional)
1018
1019
  - `application/json`
1019
1020
  - `application/x-www-form-urlencoded`
1020
1021
  - `application/graphql`
1022
+ - `multipart/form-data` (requires `SECURENOW_CAPTURE_MULTIPART=1`)
1021
1023
 
1022
- **Note:** Multipart form data (file uploads) are NOT captured by design.
1024
+ ### Multipart Body Capture (v5.8.0+)
1025
+
1026
+ Enable with `SECURENOW_CAPTURE_MULTIPART=1` to capture multipart/form-data requests. Uses a streaming parser that never buffers file content — memory stays at ~few KB regardless of upload size.
1027
+
1028
+ **What gets captured:**
1029
+ - **Text fields** — field name and value (up to 1000 chars), with sensitive fields auto-redacted
1030
+ - **File fields** — metadata only: field name, filename, content-type, and size in bytes
1031
+
1032
+ **Example trace attribute:**
1033
+ ```json
1034
+ {
1035
+ "fields": { "description": "My upload", "token": "[REDACTED]" },
1036
+ "files": [
1037
+ { "field": "avatar", "filename": "photo.jpg", "contentType": "image/jpeg", "size": 524288 },
1038
+ { "field": "resume", "filename": "cv.pdf", "contentType": "application/pdf", "size": 1048576 }
1039
+ ]
1040
+ }
1041
+ ```
1042
+
1043
+ File binary content is never stored in traces.
1023
1044
 
1024
1045
  ### Sensitive Data Redaction
1025
1046
 
package/README.md CHANGED
@@ -168,6 +168,9 @@ OTEL_EXPORTER_OTLP_HEADERS="x-api-key=..." # Authentication headers
168
168
  SECURENOW_CAPTURE_BODY=1 # Capture request bodies in traces
169
169
  SECURENOW_MAX_BODY_SIZE=10240 # Max body size in bytes
170
170
  SECURENOW_SENSITIVE_FIELDS="field1,field2" # Additional fields to redact
171
+
172
+ # Optional: Multipart body capture (file upload metadata)
173
+ SECURENOW_CAPTURE_MULTIPART=1 # Capture multipart field names, values & file metadata
171
174
  ```
172
175
 
173
176
  ### Legacy Environment Variables (still supported)
@@ -16,6 +16,7 @@ Complete reference for all environment variables supported by SecureNow.
16
16
  | **SECURENOW_CAPTURE_BODY** | Optional | `0` | Enable request body capture |
17
17
  | **SECURENOW_MAX_BODY_SIZE** | Optional | `10240` | Max body size in bytes |
18
18
  | **SECURENOW_SENSITIVE_FIELDS** | Optional | - | Comma-separated list of fields to redact |
19
+ | **SECURENOW_CAPTURE_MULTIPART** | Optional | `0` | Enable multipart/form-data streaming capture |
19
20
  | **SECURENOW_DISABLE_INSTRUMENTATIONS** | Optional | - | Comma-separated list of packages to disable |
20
21
  | **SECURENOW_TEST_SPAN** | Optional | `0` | Emit test span on startup |
21
22
  | **OTEL_SERVICE_NAME** | Optional | - | Alternative to SECURENOW_APPID |
@@ -279,8 +280,8 @@ export SECURENOW_CAPTURE_BODY=1
279
280
  - `application/x-www-form-urlencoded`
280
281
  - `application/graphql`
281
282
 
282
- **Not captured:**
283
- - `multipart/form-data` (file uploads)
283
+ **Not captured (unless separately enabled):**
284
+ - `multipart/form-data` — requires `SECURENOW_CAPTURE_MULTIPART=1` (see below)
284
285
  - Bodies larger than `SECURENOW_MAX_BODY_SIZE`
285
286
 
286
287
  **Security:**
@@ -346,6 +347,50 @@ export SECURENOW_SENSITIVE_FIELDS="custom_secret,private_data,internal_id"
346
347
 
347
348
  ---
348
349
 
350
+ ### SECURENOW_CAPTURE_MULTIPART
351
+
352
+ **Description:** Enable capture of `multipart/form-data` request bodies (file upload metadata and text fields). Uses a streaming parser that processes boundary markers on the fly — file binary content is never buffered or stored.
353
+
354
+ **Format:** `1` (enabled) or `0` (disabled)
355
+
356
+ **Default:** `0` (disabled)
357
+
358
+ **Example:**
359
+ ```bash
360
+ export SECURENOW_CAPTURE_MULTIPART=1
361
+ ```
362
+
363
+ **What gets captured:**
364
+ - **Text fields** — field name and value (up to 1000 characters), with sensitive fields auto-redacted
365
+ - **File fields** — metadata only: field name, filename, content-type, and size in bytes (no binary content)
366
+
367
+ **Example span attribute (`http.request.body`):**
368
+ ```json
369
+ {
370
+ "fields": { "description": "My upload", "token": "[REDACTED]" },
371
+ "files": [
372
+ { "field": "avatar", "filename": "photo.jpg", "contentType": "image/jpeg", "size": 524288 },
373
+ { "field": "document", "filename": "report.pdf", "contentType": "application/pdf", "size": 1048576 }
374
+ ]
375
+ }
376
+ ```
377
+
378
+ **Additional span attributes set:**
379
+ - `http.request.body.type` = `"multipart"`
380
+ - `http.request.body.size` — total raw request body size in bytes
381
+ - `http.request.body.fields_count` — number of text fields
382
+ - `http.request.body.files_count` — number of file fields
383
+
384
+ **Memory:** Bounded at ~few KB regardless of upload size (streaming parser discards file content as it passes through).
385
+
386
+ **Parts limit:** 100 parts maximum per request (safety guard).
387
+
388
+ **Requires:** `SECURENOW_CAPTURE_BODY=1` must also be set (multipart capture is gated behind general body capture).
389
+
390
+ **Since:** v5.8.0
391
+
392
+ ---
393
+
349
394
  ## Instrumentation Control
350
395
 
351
396
  ### SECURENOW_DISABLE_INSTRUMENTATIONS
@@ -192,6 +192,7 @@ import express from 'express';
192
192
  | `SECURENOW_CAPTURE_BODY` | Enable body capture (`1` or `true`) | `0` (disabled) |
193
193
  | `SECURENOW_MAX_BODY_SIZE` | Max body size in bytes | `10240` (10KB) |
194
194
  | `SECURENOW_SENSITIVE_FIELDS` | Comma-separated additional sensitive fields | (see below) |
195
+ | `SECURENOW_CAPTURE_MULTIPART` | Enable multipart/form-data streaming capture (`1` or `true`) | `0` (disabled) |
195
196
 
196
197
  ### Default Sensitive Fields
197
198
 
@@ -274,10 +275,10 @@ pm2 logs express-api --lines 100
274
275
  | `application/json` | ✅ Yes | ✅ Yes | ✅ Yes |
275
276
  | `application/graphql` | ✅ Yes | ✅ Yes | ✅ Yes |
276
277
  | `application/x-www-form-urlencoded` | ✅ Yes | ✅ Yes | ✅ Yes |
277
- | `multipart/form-data` | No | N/A | N/A |
278
+ | `multipart/form-data` | Metadata | Streaming | Yes |
278
279
  | `text/plain` | ❌ No | N/A | N/A |
279
280
 
280
- **Note**: File uploads (`multipart/form-data`) are intentionally NOT captured for performance and privacy reasons.
281
+ **Note**: Multipart capture requires `SECURENOW_CAPTURE_MULTIPART=1` (v5.8.0+). Uses a streaming parser text field values and file metadata (name, filename, content-type, size) are captured; file binary content is never buffered or stored.
281
282
 
282
283
  ## 🔍 Example: Complete Express + PM2 Setup
283
284
 
@@ -55,16 +55,24 @@ SECURENOW_SENSITIVE_FIELDS=credit_card,email,phone
55
55
  ```
56
56
  Parsed into object and sensitive fields redacted.
57
57
 
58
- 4. **Multipart** (`multipart/form-data`) - NOT Captured
59
- ```
60
- [MULTIPART - NOT CAPTURED]
58
+ 4. **Multipart** (`multipart/form-data`) - Streaming Metadata Capture (v5.8.0+)
59
+
60
+ Requires `SECURENOW_CAPTURE_MULTIPART=1`. Uses a streaming parser — file binary content is never buffered.
61
+
62
+ ```json
63
+ {
64
+ "fields": { "description": "Profile update", "token": "[REDACTED]" },
65
+ "files": [
66
+ { "field": "avatar", "filename": "photo.jpg", "contentType": "image/jpeg", "size": 524288 }
67
+ ]
68
+ }
61
69
  ```
62
- *File uploads are not captured at all (by design) - too large and unnecessary*
70
+ Text field values are captured with sensitive-field redaction. File parts record metadata only (field, filename, content-type, size). Memory stays at ~few KB regardless of upload size.
63
71
 
64
72
  ### ❌ What's NOT Captured
65
73
 
66
74
  - GET requests (no body)
67
- - File uploads (too large)
75
+ - File binary content (only metadata when multipart capture is enabled)
68
76
  - Bodies larger than max size
69
77
  - Binary data
70
78
  - Non-POST/PUT/PATCH requests
@@ -218,6 +226,7 @@ mutation Login {
218
226
  | `SECURENOW_CAPTURE_BODY` | `0` (disabled) | Enable body capture |
219
227
  | `SECURENOW_MAX_BODY_SIZE` | `10240` (10KB) | Maximum body size to capture |
220
228
  | `SECURENOW_SENSITIVE_FIELDS` | `` | Comma-separated custom sensitive fields |
229
+ | `SECURENOW_CAPTURE_MULTIPART` | `0` (disabled) | Enable multipart/form-data streaming capture (v5.8.0+) |
221
230
 
222
231
  ### Programmatic (Next.js)
223
232
 
@@ -529,7 +538,7 @@ SECURENOW_SENSITIVE_FIELDS="" # Don't do this!
529
538
 
530
539
  ### Q: Does this work with file uploads?
531
540
 
532
- **A:** No, multipart/form-data is not captured (by design). Only metadata is logged.
541
+ **A:** Yes! Since v5.8.0, set `SECURENOW_CAPTURE_MULTIPART=1` to capture multipart/form-data requests. The streaming parser extracts text field values and file metadata (name, filename, content-type, size) without ever buffering file binary content. Memory stays bounded at ~few KB regardless of upload size.
533
542
 
534
543
  ### Q: What's the performance impact?
535
544
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "5.8.0",
3
+ "version": "5.8.1",
4
4
  "description": "OpenTelemetry instrumentation for Node.js, Next.js, and Nuxt - Send traces and logs to any OTLP-compatible backend",
5
5
  "type": "commonjs",
6
6
  "main": "register.js",