securenow 4.0.5 → 4.0.9
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/README.md +4 -3
- package/cli.js +4 -1
- package/docs/ARCHITECTURE.md +408 -0
- package/{AUTO-BODY-CAPTURE.md → docs/AUTO-BODY-CAPTURE.md} +3 -0
- package/docs/AUTO-SETUP-SUMMARY.md +331 -0
- package/{AUTO-SETUP.md → docs/AUTO-SETUP.md} +3 -0
- package/{AUTOMATIC-IP-CAPTURE.md → docs/AUTOMATIC-IP-CAPTURE.md} +3 -0
- package/{BODY-CAPTURE-FIX.md → docs/BODY-CAPTURE-FIX.md} +3 -0
- package/{BODY-CAPTURE-QUICKSTART.md → docs/BODY-CAPTURE-QUICKSTART.md} +147 -147
- package/docs/CHANGELOG-NEXTJS.md +235 -0
- package/docs/COMPLETION-REPORT.md +408 -0
- package/{EASIEST-SETUP.md → docs/EASIEST-SETUP.md} +3 -0
- package/docs/EXPRESS-BODY-CAPTURE.md +1027 -0
- package/{FINAL-SOLUTION.md → docs/FINAL-SOLUTION.md} +3 -0
- package/docs/IMPLEMENTATION-SUMMARY.md +410 -0
- package/docs/INDEX.md +129 -0
- package/{NEXTJS-BODY-CAPTURE-COMPARISON.md → docs/NEXTJS-BODY-CAPTURE-COMPARISON.md} +3 -0
- package/docs/NEXTJS-WEBPACK-WARNINGS.md +267 -0
- package/{NEXTJS-WRAPPER-APPROACH.md → docs/NEXTJS-WRAPPER-APPROACH.md} +3 -0
- package/{QUICKSTART-BODY-CAPTURE.md → docs/QUICKSTART-BODY-CAPTURE.md} +3 -0
- package/{REDACTION-EXAMPLES.md → docs/REDACTION-EXAMPLES.md} +3 -0
- package/{REQUEST-BODY-CAPTURE.md → docs/REQUEST-BODY-CAPTURE.md} +575 -575
- package/{SOLUTION-SUMMARY.md → docs/SOLUTION-SUMMARY.md} +3 -0
- package/docs/VERCEL-OTEL-MIGRATION.md +255 -0
- package/examples/README.md +3 -0
- package/examples/instrumentation-with-auto-capture.ts +3 -0
- package/examples/next.config.js +3 -0
- package/examples/nextjs-api-route-with-body-capture.ts +3 -0
- package/examples/nextjs-env-example.txt +3 -0
- package/examples/nextjs-instrumentation.js +3 -0
- package/examples/nextjs-instrumentation.ts +3 -0
- package/examples/nextjs-middleware.js +3 -0
- package/examples/nextjs-middleware.ts +3 -0
- package/examples/nextjs-with-options.ts +3 -0
- package/examples/test-nextjs-setup.js +3 -0
- package/nextjs-auto-capture.js +3 -0
- package/nextjs-middleware.js +3 -0
- package/nextjs-wrapper.js +3 -0
- package/nextjs.js +174 -72
- package/package.json +3 -19
- package/postinstall.js +310 -310
- package/tracing.js +287 -287
- /package/{CUSTOMER-GUIDE.md → docs/CUSTOMER-GUIDE.md} +0 -0
- /package/{NEXTJS-BODY-CAPTURE.md → docs/NEXTJS-BODY-CAPTURE.md} +0 -0
- /package/{NEXTJS-GUIDE.md → docs/NEXTJS-GUIDE.md} +0 -0
- /package/{NEXTJS-QUICKSTART.md → docs/NEXTJS-QUICKSTART.md} +0 -0
|
@@ -1,575 +1,575 @@
|
|
|
1
|
-
# 📝 Request Body Capture - Complete Guide
|
|
2
|
-
|
|
3
|
-
SecureNow can automatically capture and trace request bodies (JSON, GraphQL, Form data) with built-in security controls!
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 🚀 Quick Start
|
|
8
|
-
|
|
9
|
-
### Enable Body Capture
|
|
10
|
-
|
|
11
|
-
Add to your `.env.local` or environment variables:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# Enable request body capture
|
|
15
|
-
SECURENOW_CAPTURE_BODY=1
|
|
16
|
-
|
|
17
|
-
# Optional: Set max body size (default: 10KB)
|
|
18
|
-
SECURENOW_MAX_BODY_SIZE=20480
|
|
19
|
-
|
|
20
|
-
# Optional: Add custom sensitive fields to redact
|
|
21
|
-
SECURENOW_SENSITIVE_FIELDS=credit_card,email,phone
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**That's it!** Request bodies are now captured automatically with sensitive data redacted.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 📊 What Gets Captured
|
|
29
|
-
|
|
30
|
-
### ✅ Supported Content Types (ALL with Redaction!)
|
|
31
|
-
|
|
32
|
-
1. **JSON** (`application/json`) - ✅ Fully Redacted
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"username": "john",
|
|
36
|
-
"password": "[REDACTED]",
|
|
37
|
-
"email": "john@example.com"
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
Sensitive object properties are automatically redacted.
|
|
41
|
-
|
|
42
|
-
2. **GraphQL** (`application/graphql`) - ✅ Fully Redacted
|
|
43
|
-
```graphql
|
|
44
|
-
mutation Login {
|
|
45
|
-
login(username: "john", password: "[REDACTED]") {
|
|
46
|
-
token
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
Sensitive fields in queries, mutations, and variables are redacted using regex pattern matching.
|
|
51
|
-
|
|
52
|
-
3. **Form Data** (`application/x-www-form-urlencoded`) - ✅ Fully Redacted
|
|
53
|
-
```
|
|
54
|
-
username=john&password=[REDACTED]&remember=true
|
|
55
|
-
```
|
|
56
|
-
Parsed into object and sensitive fields redacted.
|
|
57
|
-
|
|
58
|
-
4. **Multipart** (`multipart/form-data`) - ❌ NOT Captured
|
|
59
|
-
```
|
|
60
|
-
[MULTIPART - NOT CAPTURED]
|
|
61
|
-
```
|
|
62
|
-
*File uploads are not captured at all (by design) - too large and unnecessary*
|
|
63
|
-
|
|
64
|
-
### ❌ What's NOT Captured
|
|
65
|
-
|
|
66
|
-
- GET requests (no body)
|
|
67
|
-
- File uploads (too large)
|
|
68
|
-
- Bodies larger than max size
|
|
69
|
-
- Binary data
|
|
70
|
-
- Non-POST/PUT/PATCH requests
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 🔒 Security Features
|
|
75
|
-
|
|
76
|
-
### Automatic Sensitive Field Redaction
|
|
77
|
-
|
|
78
|
-
These fields are **automatically redacted**:
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
// Built-in sensitive fields
|
|
82
|
-
[
|
|
83
|
-
'password', 'passwd', 'pwd',
|
|
84
|
-
'secret', 'token', 'api_key', 'apikey',
|
|
85
|
-
'access_token', 'auth', 'credentials',
|
|
86
|
-
'mysql_pwd', 'stripeToken',
|
|
87
|
-
'card', 'cardnumber', 'ccv', 'cvc', 'cvv',
|
|
88
|
-
'ssn', 'pin'
|
|
89
|
-
]
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
**Example:**
|
|
93
|
-
```json
|
|
94
|
-
// Original request
|
|
95
|
-
{
|
|
96
|
-
"username": "john",
|
|
97
|
-
"password": "super_secret_123",
|
|
98
|
-
"api_key": "sk_live_..."
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Captured in trace
|
|
102
|
-
{
|
|
103
|
-
"username": "john",
|
|
104
|
-
"password": "[REDACTED]",
|
|
105
|
-
"api_key": "[REDACTED]"
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Add Custom Sensitive Fields
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
# Add your own sensitive fields
|
|
113
|
-
SECURENOW_SENSITIVE_FIELDS=credit_card,email,phone,address,dob
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Now these fields will also be redacted:
|
|
117
|
-
```json
|
|
118
|
-
{
|
|
119
|
-
"username": "john",
|
|
120
|
-
"email": "[REDACTED]",
|
|
121
|
-
"phone": "[REDACTED]",
|
|
122
|
-
"address": "[REDACTED]"
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Size Limits
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# Default: 10KB (10240 bytes)
|
|
130
|
-
SECURENOW_MAX_BODY_SIZE=10240
|
|
131
|
-
|
|
132
|
-
# Increase for larger payloads
|
|
133
|
-
SECURENOW_MAX_BODY_SIZE=50000
|
|
134
|
-
|
|
135
|
-
# Bodies larger than this show: [TOO LARGE: X bytes]
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## 💡 Usage Examples
|
|
141
|
-
|
|
142
|
-
### Next.js API Route
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
// app/api/users/route.ts
|
|
146
|
-
export async function POST(request: Request) {
|
|
147
|
-
const body = await request.json();
|
|
148
|
-
|
|
149
|
-
// Body is automatically captured in traces!
|
|
150
|
-
// password fields are redacted
|
|
151
|
-
|
|
152
|
-
return Response.json({ success: true });
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Trace will show:**
|
|
157
|
-
```json
|
|
158
|
-
{
|
|
159
|
-
"http.request.body": "{\"username\":\"john\",\"password\":\"[REDACTED]\"}",
|
|
160
|
-
"http.request.body.size": 156,
|
|
161
|
-
"http.request.body.type": "json"
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Express.js
|
|
166
|
-
|
|
167
|
-
```javascript
|
|
168
|
-
// server.js
|
|
169
|
-
const express = require('express');
|
|
170
|
-
const app = express();
|
|
171
|
-
|
|
172
|
-
app.use(express.json());
|
|
173
|
-
|
|
174
|
-
app.post('/api/login', (req, res) => {
|
|
175
|
-
// req.body is automatically captured!
|
|
176
|
-
// Sensitive fields are redacted
|
|
177
|
-
|
|
178
|
-
res.json({ success: true });
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### GraphQL
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
// GraphQL queries are captured WITH REDACTION
|
|
186
|
-
POST /graphql
|
|
187
|
-
Content-Type: application/graphql
|
|
188
|
-
|
|
189
|
-
mutation Login {
|
|
190
|
-
login(username: "john", password: "secret123", token: "abc") {
|
|
191
|
-
user { name }
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Trace shows (with sensitive fields redacted):**
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"http.request.body": "mutation Login { login(username: \"john\", password: \"[REDACTED]\", token: \"[REDACTED]\") { user { name } } }",
|
|
200
|
-
"http.request.body.type": "graphql",
|
|
201
|
-
"http.request.body.size": 245
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
**GraphQL redaction works on:**
|
|
206
|
-
- Arguments: `password: "value"` → `password: "[REDACTED]"`
|
|
207
|
-
- Variables: `$token: "value"` → `$token: "[REDACTED]"`
|
|
208
|
-
- Inline values in queries and mutations
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## 🎯 Configuration Options
|
|
213
|
-
|
|
214
|
-
### Environment Variables
|
|
215
|
-
|
|
216
|
-
| Variable | Default | Description |
|
|
217
|
-
|----------|---------|-------------|
|
|
218
|
-
| `SECURENOW_CAPTURE_BODY` | `0` (disabled) | Enable body capture |
|
|
219
|
-
| `SECURENOW_MAX_BODY_SIZE` | `10240` (10KB) | Maximum body size to capture |
|
|
220
|
-
| `SECURENOW_SENSITIVE_FIELDS` | `` | Comma-separated custom sensitive fields |
|
|
221
|
-
|
|
222
|
-
### Programmatic (Next.js)
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
// instrumentation.ts
|
|
226
|
-
import { registerSecureNow } from 'securenow/nextjs';
|
|
227
|
-
|
|
228
|
-
export function register() {
|
|
229
|
-
registerSecureNow({
|
|
230
|
-
serviceName: 'my-app',
|
|
231
|
-
captureBody: true, // Enable body capture
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## 🔍 Viewing in SigNoz
|
|
239
|
-
|
|
240
|
-
### Query Examples
|
|
241
|
-
|
|
242
|
-
**Find all requests with specific body content:**
|
|
243
|
-
```
|
|
244
|
-
http.request.body CONTAINS "username"
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
**Find failed login attempts:**
|
|
248
|
-
```
|
|
249
|
-
http.target = "/api/login"
|
|
250
|
-
AND http.status_code = 401
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
**Group by API endpoint and body size:**
|
|
254
|
-
```sql
|
|
255
|
-
SELECT
|
|
256
|
-
http.target,
|
|
257
|
-
AVG(http.request.body.size) as avg_body_size,
|
|
258
|
-
COUNT(*) as requests
|
|
259
|
-
FROM spans
|
|
260
|
-
WHERE http.request.body.size IS NOT NULL
|
|
261
|
-
GROUP BY http.target
|
|
262
|
-
ORDER BY avg_body_size DESC
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
**Find large payloads:**
|
|
266
|
-
```
|
|
267
|
-
http.request.body.size > 5000
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
## ⚠️ Privacy & Compliance
|
|
273
|
-
|
|
274
|
-
### GDPR Considerations
|
|
275
|
-
|
|
276
|
-
Request bodies may contain personal data. Consider:
|
|
277
|
-
|
|
278
|
-
1. **Legal Basis** - Ensure you have legitimate interest or consent
|
|
279
|
-
2. **Data Minimization** - Only capture what you need
|
|
280
|
-
3. **Retention** - Configure SigNoz retention policies
|
|
281
|
-
4. **Anonymization** - Add more fields to redact list
|
|
282
|
-
|
|
283
|
-
### PCI-DSS Compliance
|
|
284
|
-
|
|
285
|
-
**Never capture card data!** Built-in protection:
|
|
286
|
-
- `card`, `cardnumber`, `cvv`, `cvc` → Automatically redacted
|
|
287
|
-
- `stripeToken` → Automatically redacted
|
|
288
|
-
|
|
289
|
-
Add more if needed:
|
|
290
|
-
```bash
|
|
291
|
-
SECURENOW_SENSITIVE_FIELDS=cardName,cardExpiry,cardCvv
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### HIPAA Compliance
|
|
295
|
-
|
|
296
|
-
Add health-related fields:
|
|
297
|
-
```bash
|
|
298
|
-
SECURENOW_SENSITIVE_FIELDS=ssn,medical_record,diagnosis,prescription
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## 🎓 Best Practices
|
|
304
|
-
|
|
305
|
-
### ✅ DO
|
|
306
|
-
|
|
307
|
-
1. **Enable in development first** - Test thoroughly
|
|
308
|
-
2. **Add custom sensitive fields** - For your specific use case
|
|
309
|
-
3. **Set appropriate size limits** - Balance detail vs storage
|
|
310
|
-
4. **Monitor storage usage** - Bodies increase trace size
|
|
311
|
-
5. **Document what you capture** - In privacy policy
|
|
312
|
-
|
|
313
|
-
### ❌ DON'T
|
|
314
|
-
|
|
315
|
-
1. **Don't capture in production without review** - Check privacy implications
|
|
316
|
-
2. **Don't increase size limits too much** - Can impact performance
|
|
317
|
-
3. **Don't rely on it for audit logs** - Use dedicated audit logging
|
|
318
|
-
4. **Don't capture file uploads** - Too large and unnecessary
|
|
319
|
-
5. **Don't forget about retention** - Old data should be deleted
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## 🐛 Debugging
|
|
324
|
-
|
|
325
|
-
### Body Not Captured?
|
|
326
|
-
|
|
327
|
-
**Check:**
|
|
328
|
-
|
|
329
|
-
1. **Is capture enabled?**
|
|
330
|
-
```bash
|
|
331
|
-
SECURENOW_CAPTURE_BODY=1
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
2. **Is it a supported method?**
|
|
335
|
-
- Only POST, PUT, PATCH
|
|
336
|
-
- Not GET, DELETE, HEAD
|
|
337
|
-
|
|
338
|
-
3. **Is it a supported content type?**
|
|
339
|
-
- JSON: ✅
|
|
340
|
-
- GraphQL: ✅
|
|
341
|
-
- Form: ✅
|
|
342
|
-
- Multipart: ❌ (by design)
|
|
343
|
-
|
|
344
|
-
4. **Is body size within limit?**
|
|
345
|
-
```bash
|
|
346
|
-
# Increase if needed
|
|
347
|
-
SECURENOW_MAX_BODY_SIZE=50000
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
5. **Check console on startup:**
|
|
351
|
-
```
|
|
352
|
-
[securenow] 📝 Request body capture: ENABLED
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
### Partial Body Captured?
|
|
356
|
-
|
|
357
|
-
Bodies are truncated if they exceed `maxBodySize`. Increase the limit:
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
SECURENOW_MAX_BODY_SIZE=50000
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Sensitive Data Not Redacted?
|
|
364
|
-
|
|
365
|
-
Add the field name:
|
|
366
|
-
|
|
367
|
-
```bash
|
|
368
|
-
SECURENOW_SENSITIVE_FIELDS=mySecretField,anotherSecret
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
Field matching is case-insensitive and uses `includes()`:
|
|
372
|
-
- `password` matches `password`, `Password`, `user_password`
|
|
373
|
-
- `token` matches `token`, `access_token`, `oauth_token`
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
## 📈 Performance Impact
|
|
378
|
-
|
|
379
|
-
### Overhead
|
|
380
|
-
|
|
381
|
-
- **Memory:** ~10-50KB per request (for body storage)
|
|
382
|
-
- **CPU:** < 1ms for redaction
|
|
383
|
-
- **Storage:** Increases trace size by body size
|
|
384
|
-
|
|
385
|
-
### Optimization Tips
|
|
386
|
-
|
|
387
|
-
1. **Set reasonable size limits**
|
|
388
|
-
```bash
|
|
389
|
-
SECURENOW_MAX_BODY_SIZE=10240 # 10KB
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
2. **Only enable where needed**
|
|
393
|
-
```typescript
|
|
394
|
-
// Enable only for specific environments
|
|
395
|
-
if (process.env.NODE_ENV === 'development') {
|
|
396
|
-
process.env.SECURENOW_CAPTURE_BODY = '1';
|
|
397
|
-
}
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
3. **Filter in SigNoz**
|
|
401
|
-
- Use sampling to reduce volume
|
|
402
|
-
- Set up trace tail sampling
|
|
403
|
-
|
|
404
|
-
---
|
|
405
|
-
|
|
406
|
-
## 🎯 Use Cases
|
|
407
|
-
|
|
408
|
-
### 1. Debug API Issues
|
|
409
|
-
|
|
410
|
-
**Problem:** Users report API errors but you can't reproduce
|
|
411
|
-
|
|
412
|
-
**Solution:** Capture body to see exact input
|
|
413
|
-
```
|
|
414
|
-
http.target = "/api/checkout"
|
|
415
|
-
AND http.status_code >= 400
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
View `http.request.body` to see what caused the error.
|
|
419
|
-
|
|
420
|
-
### 2. Monitor GraphQL Queries
|
|
421
|
-
|
|
422
|
-
**Problem:** Need to optimize slow GraphQL queries
|
|
423
|
-
|
|
424
|
-
**Solution:** Capture GraphQL bodies
|
|
425
|
-
```
|
|
426
|
-
http.request.body CONTAINS "query"
|
|
427
|
-
AND duration > 1000ms
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
See which queries are slow.
|
|
431
|
-
|
|
432
|
-
### 3. Track Feature Usage
|
|
433
|
-
|
|
434
|
-
**Problem:** Want to know which API features are used
|
|
435
|
-
|
|
436
|
-
**Solution:** Analyze request bodies
|
|
437
|
-
```sql
|
|
438
|
-
SELECT
|
|
439
|
-
COUNT(*) as usage,
|
|
440
|
-
http.request.body
|
|
441
|
-
FROM spans
|
|
442
|
-
WHERE http.target = "/api/features"
|
|
443
|
-
GROUP BY http.request.body
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### 4. Validate Input Patterns
|
|
447
|
-
|
|
448
|
-
**Problem:** Need to understand common input patterns
|
|
449
|
-
|
|
450
|
-
**Solution:** Review captured bodies
|
|
451
|
-
```
|
|
452
|
-
http.target = "/api/search"
|
|
453
|
-
AND http.method = "POST"
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
---
|
|
457
|
-
|
|
458
|
-
## 🔧 Advanced Configuration
|
|
459
|
-
|
|
460
|
-
### Custom Redaction Logic
|
|
461
|
-
|
|
462
|
-
For more complex redaction, you can use OpenTelemetry SpanProcessor:
|
|
463
|
-
|
|
464
|
-
```typescript
|
|
465
|
-
// instrumentation.ts
|
|
466
|
-
import { trace } from '@opentelemetry/api';
|
|
467
|
-
import { registerSecureNow } from 'securenow/nextjs';
|
|
468
|
-
|
|
469
|
-
class CustomRedactionProcessor {
|
|
470
|
-
onStart(span) {
|
|
471
|
-
// Custom logic here
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
onEnd(span) {
|
|
475
|
-
const body = span.attributes['http.request.body'];
|
|
476
|
-
if (body && typeof body === 'string') {
|
|
477
|
-
// Apply custom redaction
|
|
478
|
-
const redacted = body.replace(/\b\d{16}\b/g, '[CARD]'); // Redact card numbers
|
|
479
|
-
span.setAttribute('http.request.body', redacted);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
export function register() {
|
|
485
|
-
registerSecureNow({ captureBody: true });
|
|
486
|
-
|
|
487
|
-
// Add custom processor
|
|
488
|
-
trace.getTracerProvider()
|
|
489
|
-
.addSpanProcessor(new CustomRedactionProcessor());
|
|
490
|
-
}
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### Conditional Capture
|
|
494
|
-
|
|
495
|
-
Enable only for specific routes:
|
|
496
|
-
|
|
497
|
-
```typescript
|
|
498
|
-
// middleware.ts
|
|
499
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
500
|
-
|
|
501
|
-
export function middleware(request: NextRequest) {
|
|
502
|
-
// Enable body capture only for API routes
|
|
503
|
-
if (request.nextUrl.pathname.startsWith('/api/')) {
|
|
504
|
-
process.env.SECURENOW_CAPTURE_BODY = '1';
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return NextResponse.next();
|
|
508
|
-
}
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
---
|
|
512
|
-
|
|
513
|
-
## ❓ FAQ
|
|
514
|
-
|
|
515
|
-
### Q: Will this capture passwords?
|
|
516
|
-
|
|
517
|
-
**A:** No! Passwords are automatically redacted. Any field with `password`, `passwd`, or `pwd` in the name shows `[REDACTED]`.
|
|
518
|
-
|
|
519
|
-
### Q: What about credit cards?
|
|
520
|
-
|
|
521
|
-
**A:** Automatically redacted. Fields with `card`, `cardnumber`, `cvv`, `cvc` are protected.
|
|
522
|
-
|
|
523
|
-
### Q: Can I disable redaction?
|
|
524
|
-
|
|
525
|
-
**A:** Not recommended! But you can clear the sensitive fields list (⚠️ dangerous):
|
|
526
|
-
```bash
|
|
527
|
-
SECURENOW_SENSITIVE_FIELDS="" # Don't do this!
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### Q: Does this work with file uploads?
|
|
531
|
-
|
|
532
|
-
**A:** No, multipart/form-data is not captured (by design). Only metadata is logged.
|
|
533
|
-
|
|
534
|
-
### Q: What's the performance impact?
|
|
535
|
-
|
|
536
|
-
**A:** Minimal. < 1ms CPU overhead, ~10-50KB memory per request.
|
|
537
|
-
|
|
538
|
-
### Q: Can I capture response bodies too?
|
|
539
|
-
|
|
540
|
-
**A:** Not yet. Feature coming soon! Track issue #XXX.
|
|
541
|
-
|
|
542
|
-
### Q: Is this GDPR compliant?
|
|
543
|
-
|
|
544
|
-
**A:** Depends on your use case. Review privacy implications and:
|
|
545
|
-
- Add relevant fields to redaction list
|
|
546
|
-
- Set appropriate retention
|
|
547
|
-
- Document in privacy policy
|
|
548
|
-
|
|
549
|
-
---
|
|
550
|
-
|
|
551
|
-
## 🎉 Summary
|
|
552
|
-
|
|
553
|
-
**Enable request body capture in 3 steps:**
|
|
554
|
-
|
|
555
|
-
1. ```bash
|
|
556
|
-
SECURENOW_CAPTURE_BODY=1
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
2. ```bash
|
|
560
|
-
# Optional: customize
|
|
561
|
-
SECURENOW_MAX_BODY_SIZE=20480
|
|
562
|
-
SECURENOW_SENSITIVE_FIELDS=email,phone
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
3. **Deploy!** Bodies are captured with sensitive data automatically redacted.
|
|
566
|
-
|
|
567
|
-
**View in SigNoz:**
|
|
568
|
-
- `http.request.body` - The captured body (redacted)
|
|
569
|
-
- `http.request.body.size` - Body size in bytes
|
|
570
|
-
- `http.request.body.type` - Content type (json, graphql, form)
|
|
571
|
-
|
|
572
|
-
---
|
|
573
|
-
|
|
574
|
-
**Made with security in mind** 🔒
|
|
575
|
-
|
|
1
|
+
# 📝 Request Body Capture - Complete Guide
|
|
2
|
+
|
|
3
|
+
SecureNow can automatically capture and trace request bodies (JSON, GraphQL, Form data) with built-in security controls!
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Quick Start
|
|
8
|
+
|
|
9
|
+
### Enable Body Capture
|
|
10
|
+
|
|
11
|
+
Add to your `.env.local` or environment variables:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Enable request body capture
|
|
15
|
+
SECURENOW_CAPTURE_BODY=1
|
|
16
|
+
|
|
17
|
+
# Optional: Set max body size (default: 10KB)
|
|
18
|
+
SECURENOW_MAX_BODY_SIZE=20480
|
|
19
|
+
|
|
20
|
+
# Optional: Add custom sensitive fields to redact
|
|
21
|
+
SECURENOW_SENSITIVE_FIELDS=credit_card,email,phone
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**That's it!** Request bodies are now captured automatically with sensitive data redacted.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📊 What Gets Captured
|
|
29
|
+
|
|
30
|
+
### ✅ Supported Content Types (ALL with Redaction!)
|
|
31
|
+
|
|
32
|
+
1. **JSON** (`application/json`) - ✅ Fully Redacted
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"username": "john",
|
|
36
|
+
"password": "[REDACTED]",
|
|
37
|
+
"email": "john@example.com"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
Sensitive object properties are automatically redacted.
|
|
41
|
+
|
|
42
|
+
2. **GraphQL** (`application/graphql`) - ✅ Fully Redacted
|
|
43
|
+
```graphql
|
|
44
|
+
mutation Login {
|
|
45
|
+
login(username: "john", password: "[REDACTED]") {
|
|
46
|
+
token
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
Sensitive fields in queries, mutations, and variables are redacted using regex pattern matching.
|
|
51
|
+
|
|
52
|
+
3. **Form Data** (`application/x-www-form-urlencoded`) - ✅ Fully Redacted
|
|
53
|
+
```
|
|
54
|
+
username=john&password=[REDACTED]&remember=true
|
|
55
|
+
```
|
|
56
|
+
Parsed into object and sensitive fields redacted.
|
|
57
|
+
|
|
58
|
+
4. **Multipart** (`multipart/form-data`) - ❌ NOT Captured
|
|
59
|
+
```
|
|
60
|
+
[MULTIPART - NOT CAPTURED]
|
|
61
|
+
```
|
|
62
|
+
*File uploads are not captured at all (by design) - too large and unnecessary*
|
|
63
|
+
|
|
64
|
+
### ❌ What's NOT Captured
|
|
65
|
+
|
|
66
|
+
- GET requests (no body)
|
|
67
|
+
- File uploads (too large)
|
|
68
|
+
- Bodies larger than max size
|
|
69
|
+
- Binary data
|
|
70
|
+
- Non-POST/PUT/PATCH requests
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 🔒 Security Features
|
|
75
|
+
|
|
76
|
+
### Automatic Sensitive Field Redaction
|
|
77
|
+
|
|
78
|
+
These fields are **automatically redacted**:
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
// Built-in sensitive fields
|
|
82
|
+
[
|
|
83
|
+
'password', 'passwd', 'pwd',
|
|
84
|
+
'secret', 'token', 'api_key', 'apikey',
|
|
85
|
+
'access_token', 'auth', 'credentials',
|
|
86
|
+
'mysql_pwd', 'stripeToken',
|
|
87
|
+
'card', 'cardnumber', 'ccv', 'cvc', 'cvv',
|
|
88
|
+
'ssn', 'pin'
|
|
89
|
+
]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Example:**
|
|
93
|
+
```json
|
|
94
|
+
// Original request
|
|
95
|
+
{
|
|
96
|
+
"username": "john",
|
|
97
|
+
"password": "super_secret_123",
|
|
98
|
+
"api_key": "sk_live_..."
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Captured in trace
|
|
102
|
+
{
|
|
103
|
+
"username": "john",
|
|
104
|
+
"password": "[REDACTED]",
|
|
105
|
+
"api_key": "[REDACTED]"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Add Custom Sensitive Fields
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Add your own sensitive fields
|
|
113
|
+
SECURENOW_SENSITIVE_FIELDS=credit_card,email,phone,address,dob
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Now these fields will also be redacted:
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"username": "john",
|
|
120
|
+
"email": "[REDACTED]",
|
|
121
|
+
"phone": "[REDACTED]",
|
|
122
|
+
"address": "[REDACTED]"
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Size Limits
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Default: 10KB (10240 bytes)
|
|
130
|
+
SECURENOW_MAX_BODY_SIZE=10240
|
|
131
|
+
|
|
132
|
+
# Increase for larger payloads
|
|
133
|
+
SECURENOW_MAX_BODY_SIZE=50000
|
|
134
|
+
|
|
135
|
+
# Bodies larger than this show: [TOO LARGE: X bytes]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 💡 Usage Examples
|
|
141
|
+
|
|
142
|
+
### Next.js API Route
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// app/api/users/route.ts
|
|
146
|
+
export async function POST(request: Request) {
|
|
147
|
+
const body = await request.json();
|
|
148
|
+
|
|
149
|
+
// Body is automatically captured in traces!
|
|
150
|
+
// password fields are redacted
|
|
151
|
+
|
|
152
|
+
return Response.json({ success: true });
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Trace will show:**
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"http.request.body": "{\"username\":\"john\",\"password\":\"[REDACTED]\"}",
|
|
160
|
+
"http.request.body.size": 156,
|
|
161
|
+
"http.request.body.type": "json"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Express.js
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
// server.js
|
|
169
|
+
const express = require('express');
|
|
170
|
+
const app = express();
|
|
171
|
+
|
|
172
|
+
app.use(express.json());
|
|
173
|
+
|
|
174
|
+
app.post('/api/login', (req, res) => {
|
|
175
|
+
// req.body is automatically captured!
|
|
176
|
+
// Sensitive fields are redacted
|
|
177
|
+
|
|
178
|
+
res.json({ success: true });
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### GraphQL
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// GraphQL queries are captured WITH REDACTION
|
|
186
|
+
POST /graphql
|
|
187
|
+
Content-Type: application/graphql
|
|
188
|
+
|
|
189
|
+
mutation Login {
|
|
190
|
+
login(username: "john", password: "secret123", token: "abc") {
|
|
191
|
+
user { name }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Trace shows (with sensitive fields redacted):**
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"http.request.body": "mutation Login { login(username: \"john\", password: \"[REDACTED]\", token: \"[REDACTED]\") { user { name } } }",
|
|
200
|
+
"http.request.body.type": "graphql",
|
|
201
|
+
"http.request.body.size": 245
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**GraphQL redaction works on:**
|
|
206
|
+
- Arguments: `password: "value"` → `password: "[REDACTED]"`
|
|
207
|
+
- Variables: `$token: "value"` → `$token: "[REDACTED]"`
|
|
208
|
+
- Inline values in queries and mutations
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 🎯 Configuration Options
|
|
213
|
+
|
|
214
|
+
### Environment Variables
|
|
215
|
+
|
|
216
|
+
| Variable | Default | Description |
|
|
217
|
+
|----------|---------|-------------|
|
|
218
|
+
| `SECURENOW_CAPTURE_BODY` | `0` (disabled) | Enable body capture |
|
|
219
|
+
| `SECURENOW_MAX_BODY_SIZE` | `10240` (10KB) | Maximum body size to capture |
|
|
220
|
+
| `SECURENOW_SENSITIVE_FIELDS` | `` | Comma-separated custom sensitive fields |
|
|
221
|
+
|
|
222
|
+
### Programmatic (Next.js)
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// instrumentation.ts
|
|
226
|
+
import { registerSecureNow } from 'securenow/nextjs';
|
|
227
|
+
|
|
228
|
+
export function register() {
|
|
229
|
+
registerSecureNow({
|
|
230
|
+
serviceName: 'my-app',
|
|
231
|
+
captureBody: true, // Enable body capture
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 🔍 Viewing in SigNoz
|
|
239
|
+
|
|
240
|
+
### Query Examples
|
|
241
|
+
|
|
242
|
+
**Find all requests with specific body content:**
|
|
243
|
+
```
|
|
244
|
+
http.request.body CONTAINS "username"
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Find failed login attempts:**
|
|
248
|
+
```
|
|
249
|
+
http.target = "/api/login"
|
|
250
|
+
AND http.status_code = 401
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Group by API endpoint and body size:**
|
|
254
|
+
```sql
|
|
255
|
+
SELECT
|
|
256
|
+
http.target,
|
|
257
|
+
AVG(http.request.body.size) as avg_body_size,
|
|
258
|
+
COUNT(*) as requests
|
|
259
|
+
FROM spans
|
|
260
|
+
WHERE http.request.body.size IS NOT NULL
|
|
261
|
+
GROUP BY http.target
|
|
262
|
+
ORDER BY avg_body_size DESC
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Find large payloads:**
|
|
266
|
+
```
|
|
267
|
+
http.request.body.size > 5000
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## ⚠️ Privacy & Compliance
|
|
273
|
+
|
|
274
|
+
### GDPR Considerations
|
|
275
|
+
|
|
276
|
+
Request bodies may contain personal data. Consider:
|
|
277
|
+
|
|
278
|
+
1. **Legal Basis** - Ensure you have legitimate interest or consent
|
|
279
|
+
2. **Data Minimization** - Only capture what you need
|
|
280
|
+
3. **Retention** - Configure SigNoz retention policies
|
|
281
|
+
4. **Anonymization** - Add more fields to redact list
|
|
282
|
+
|
|
283
|
+
### PCI-DSS Compliance
|
|
284
|
+
|
|
285
|
+
**Never capture card data!** Built-in protection:
|
|
286
|
+
- `card`, `cardnumber`, `cvv`, `cvc` → Automatically redacted
|
|
287
|
+
- `stripeToken` → Automatically redacted
|
|
288
|
+
|
|
289
|
+
Add more if needed:
|
|
290
|
+
```bash
|
|
291
|
+
SECURENOW_SENSITIVE_FIELDS=cardName,cardExpiry,cardCvv
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### HIPAA Compliance
|
|
295
|
+
|
|
296
|
+
Add health-related fields:
|
|
297
|
+
```bash
|
|
298
|
+
SECURENOW_SENSITIVE_FIELDS=ssn,medical_record,diagnosis,prescription
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 🎓 Best Practices
|
|
304
|
+
|
|
305
|
+
### ✅ DO
|
|
306
|
+
|
|
307
|
+
1. **Enable in development first** - Test thoroughly
|
|
308
|
+
2. **Add custom sensitive fields** - For your specific use case
|
|
309
|
+
3. **Set appropriate size limits** - Balance detail vs storage
|
|
310
|
+
4. **Monitor storage usage** - Bodies increase trace size
|
|
311
|
+
5. **Document what you capture** - In privacy policy
|
|
312
|
+
|
|
313
|
+
### ❌ DON'T
|
|
314
|
+
|
|
315
|
+
1. **Don't capture in production without review** - Check privacy implications
|
|
316
|
+
2. **Don't increase size limits too much** - Can impact performance
|
|
317
|
+
3. **Don't rely on it for audit logs** - Use dedicated audit logging
|
|
318
|
+
4. **Don't capture file uploads** - Too large and unnecessary
|
|
319
|
+
5. **Don't forget about retention** - Old data should be deleted
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 🐛 Debugging
|
|
324
|
+
|
|
325
|
+
### Body Not Captured?
|
|
326
|
+
|
|
327
|
+
**Check:**
|
|
328
|
+
|
|
329
|
+
1. **Is capture enabled?**
|
|
330
|
+
```bash
|
|
331
|
+
SECURENOW_CAPTURE_BODY=1
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
2. **Is it a supported method?**
|
|
335
|
+
- Only POST, PUT, PATCH
|
|
336
|
+
- Not GET, DELETE, HEAD
|
|
337
|
+
|
|
338
|
+
3. **Is it a supported content type?**
|
|
339
|
+
- JSON: ✅
|
|
340
|
+
- GraphQL: ✅
|
|
341
|
+
- Form: ✅
|
|
342
|
+
- Multipart: ❌ (by design)
|
|
343
|
+
|
|
344
|
+
4. **Is body size within limit?**
|
|
345
|
+
```bash
|
|
346
|
+
# Increase if needed
|
|
347
|
+
SECURENOW_MAX_BODY_SIZE=50000
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
5. **Check console on startup:**
|
|
351
|
+
```
|
|
352
|
+
[securenow] 📝 Request body capture: ENABLED
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Partial Body Captured?
|
|
356
|
+
|
|
357
|
+
Bodies are truncated if they exceed `maxBodySize`. Increase the limit:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
SECURENOW_MAX_BODY_SIZE=50000
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Sensitive Data Not Redacted?
|
|
364
|
+
|
|
365
|
+
Add the field name:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
SECURENOW_SENSITIVE_FIELDS=mySecretField,anotherSecret
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Field matching is case-insensitive and uses `includes()`:
|
|
372
|
+
- `password` matches `password`, `Password`, `user_password`
|
|
373
|
+
- `token` matches `token`, `access_token`, `oauth_token`
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## 📈 Performance Impact
|
|
378
|
+
|
|
379
|
+
### Overhead
|
|
380
|
+
|
|
381
|
+
- **Memory:** ~10-50KB per request (for body storage)
|
|
382
|
+
- **CPU:** < 1ms for redaction
|
|
383
|
+
- **Storage:** Increases trace size by body size
|
|
384
|
+
|
|
385
|
+
### Optimization Tips
|
|
386
|
+
|
|
387
|
+
1. **Set reasonable size limits**
|
|
388
|
+
```bash
|
|
389
|
+
SECURENOW_MAX_BODY_SIZE=10240 # 10KB
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
2. **Only enable where needed**
|
|
393
|
+
```typescript
|
|
394
|
+
// Enable only for specific environments
|
|
395
|
+
if (process.env.NODE_ENV === 'development') {
|
|
396
|
+
process.env.SECURENOW_CAPTURE_BODY = '1';
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
3. **Filter in SigNoz**
|
|
401
|
+
- Use sampling to reduce volume
|
|
402
|
+
- Set up trace tail sampling
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 🎯 Use Cases
|
|
407
|
+
|
|
408
|
+
### 1. Debug API Issues
|
|
409
|
+
|
|
410
|
+
**Problem:** Users report API errors but you can't reproduce
|
|
411
|
+
|
|
412
|
+
**Solution:** Capture body to see exact input
|
|
413
|
+
```
|
|
414
|
+
http.target = "/api/checkout"
|
|
415
|
+
AND http.status_code >= 400
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
View `http.request.body` to see what caused the error.
|
|
419
|
+
|
|
420
|
+
### 2. Monitor GraphQL Queries
|
|
421
|
+
|
|
422
|
+
**Problem:** Need to optimize slow GraphQL queries
|
|
423
|
+
|
|
424
|
+
**Solution:** Capture GraphQL bodies
|
|
425
|
+
```
|
|
426
|
+
http.request.body CONTAINS "query"
|
|
427
|
+
AND duration > 1000ms
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
See which queries are slow.
|
|
431
|
+
|
|
432
|
+
### 3. Track Feature Usage
|
|
433
|
+
|
|
434
|
+
**Problem:** Want to know which API features are used
|
|
435
|
+
|
|
436
|
+
**Solution:** Analyze request bodies
|
|
437
|
+
```sql
|
|
438
|
+
SELECT
|
|
439
|
+
COUNT(*) as usage,
|
|
440
|
+
http.request.body
|
|
441
|
+
FROM spans
|
|
442
|
+
WHERE http.target = "/api/features"
|
|
443
|
+
GROUP BY http.request.body
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### 4. Validate Input Patterns
|
|
447
|
+
|
|
448
|
+
**Problem:** Need to understand common input patterns
|
|
449
|
+
|
|
450
|
+
**Solution:** Review captured bodies
|
|
451
|
+
```
|
|
452
|
+
http.target = "/api/search"
|
|
453
|
+
AND http.method = "POST"
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 🔧 Advanced Configuration
|
|
459
|
+
|
|
460
|
+
### Custom Redaction Logic
|
|
461
|
+
|
|
462
|
+
For more complex redaction, you can use OpenTelemetry SpanProcessor:
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
// instrumentation.ts
|
|
466
|
+
import { trace } from '@opentelemetry/api';
|
|
467
|
+
import { registerSecureNow } from 'securenow/nextjs';
|
|
468
|
+
|
|
469
|
+
class CustomRedactionProcessor {
|
|
470
|
+
onStart(span) {
|
|
471
|
+
// Custom logic here
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
onEnd(span) {
|
|
475
|
+
const body = span.attributes['http.request.body'];
|
|
476
|
+
if (body && typeof body === 'string') {
|
|
477
|
+
// Apply custom redaction
|
|
478
|
+
const redacted = body.replace(/\b\d{16}\b/g, '[CARD]'); // Redact card numbers
|
|
479
|
+
span.setAttribute('http.request.body', redacted);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
export function register() {
|
|
485
|
+
registerSecureNow({ captureBody: true });
|
|
486
|
+
|
|
487
|
+
// Add custom processor
|
|
488
|
+
trace.getTracerProvider()
|
|
489
|
+
.addSpanProcessor(new CustomRedactionProcessor());
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Conditional Capture
|
|
494
|
+
|
|
495
|
+
Enable only for specific routes:
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
// middleware.ts
|
|
499
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
500
|
+
|
|
501
|
+
export function middleware(request: NextRequest) {
|
|
502
|
+
// Enable body capture only for API routes
|
|
503
|
+
if (request.nextUrl.pathname.startsWith('/api/')) {
|
|
504
|
+
process.env.SECURENOW_CAPTURE_BODY = '1';
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return NextResponse.next();
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## ❓ FAQ
|
|
514
|
+
|
|
515
|
+
### Q: Will this capture passwords?
|
|
516
|
+
|
|
517
|
+
**A:** No! Passwords are automatically redacted. Any field with `password`, `passwd`, or `pwd` in the name shows `[REDACTED]`.
|
|
518
|
+
|
|
519
|
+
### Q: What about credit cards?
|
|
520
|
+
|
|
521
|
+
**A:** Automatically redacted. Fields with `card`, `cardnumber`, `cvv`, `cvc` are protected.
|
|
522
|
+
|
|
523
|
+
### Q: Can I disable redaction?
|
|
524
|
+
|
|
525
|
+
**A:** Not recommended! But you can clear the sensitive fields list (⚠️ dangerous):
|
|
526
|
+
```bash
|
|
527
|
+
SECURENOW_SENSITIVE_FIELDS="" # Don't do this!
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Q: Does this work with file uploads?
|
|
531
|
+
|
|
532
|
+
**A:** No, multipart/form-data is not captured (by design). Only metadata is logged.
|
|
533
|
+
|
|
534
|
+
### Q: What's the performance impact?
|
|
535
|
+
|
|
536
|
+
**A:** Minimal. < 1ms CPU overhead, ~10-50KB memory per request.
|
|
537
|
+
|
|
538
|
+
### Q: Can I capture response bodies too?
|
|
539
|
+
|
|
540
|
+
**A:** Not yet. Feature coming soon! Track issue #XXX.
|
|
541
|
+
|
|
542
|
+
### Q: Is this GDPR compliant?
|
|
543
|
+
|
|
544
|
+
**A:** Depends on your use case. Review privacy implications and:
|
|
545
|
+
- Add relevant fields to redaction list
|
|
546
|
+
- Set appropriate retention
|
|
547
|
+
- Document in privacy policy
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## 🎉 Summary
|
|
552
|
+
|
|
553
|
+
**Enable request body capture in 3 steps:**
|
|
554
|
+
|
|
555
|
+
1. ```bash
|
|
556
|
+
SECURENOW_CAPTURE_BODY=1
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
2. ```bash
|
|
560
|
+
# Optional: customize
|
|
561
|
+
SECURENOW_MAX_BODY_SIZE=20480
|
|
562
|
+
SECURENOW_SENSITIVE_FIELDS=email,phone
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
3. **Deploy!** Bodies are captured with sensitive data automatically redacted.
|
|
566
|
+
|
|
567
|
+
**View in SigNoz:**
|
|
568
|
+
- `http.request.body` - The captured body (redacted)
|
|
569
|
+
- `http.request.body.size` - Body size in bytes
|
|
570
|
+
- `http.request.body.type` - Content type (json, graphql, form)
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
**Made with security in mind** 🔒
|
|
575
|
+
|