securenow 7.6.7 → 7.6.8

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.
Files changed (67) hide show
  1. package/NPM_README.md +13 -13
  2. package/README.md +21 -37
  3. package/app-config.js +5 -3
  4. package/cli/config.js +4 -3
  5. package/cli/diagnostics.js +54 -15
  6. package/cli/run.js +40 -11
  7. package/firewall-only.js +1 -1
  8. package/mcp/catalog.js +1 -1
  9. package/nextjs-webpack-config.js +3 -15
  10. package/nextjs.js +21 -23
  11. package/nuxt-server-plugin.mjs +20 -10
  12. package/package.json +33 -34
  13. package/register.js +1 -1
  14. package/tracing.js +17 -7
  15. package/web-vite.mjs +23 -13
  16. package/CONSUMING-APPS-GUIDE.md +0 -463
  17. package/docs/ALL-FRAMEWORKS-QUICKSTART.md +0 -1388
  18. package/docs/API-KEYS-GUIDE.md +0 -278
  19. package/docs/ARCHITECTURE.md +0 -408
  20. package/docs/AUTO-BODY-CAPTURE.md +0 -412
  21. package/docs/AUTO-SETUP-SUMMARY.md +0 -331
  22. package/docs/AUTO-SETUP.md +0 -419
  23. package/docs/AUTOMATIC-IP-CAPTURE.md +0 -359
  24. package/docs/BODY-CAPTURE-FIX.md +0 -261
  25. package/docs/BODY-CAPTURE-QUICKSTART.md +0 -147
  26. package/docs/CHANGELOG-NEXTJS.md +0 -235
  27. package/docs/COMPLETION-REPORT.md +0 -408
  28. package/docs/CUSTOMER-GUIDE.md +0 -364
  29. package/docs/EASIEST-SETUP.md +0 -342
  30. package/docs/ENVIRONMENT-VARIABLES.md +0 -166
  31. package/docs/ENVIRONMENTS.md +0 -60
  32. package/docs/EXPRESS-BODY-CAPTURE.md +0 -1028
  33. package/docs/EXPRESS-SETUP-GUIDE.md +0 -722
  34. package/docs/FINAL-SOLUTION.md +0 -335
  35. package/docs/FIREWALL-GUIDE.md +0 -440
  36. package/docs/IMPLEMENTATION-SUMMARY.md +0 -410
  37. package/docs/INDEX.md +0 -222
  38. package/docs/LOGGING-GUIDE.md +0 -704
  39. package/docs/LOGGING-QUICKSTART.md +0 -221
  40. package/docs/MCP-GUIDE.md +0 -58
  41. package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +0 -323
  42. package/docs/NEXTJS-BODY-CAPTURE.md +0 -368
  43. package/docs/NEXTJS-GUIDE.md +0 -392
  44. package/docs/NEXTJS-QUICKSTART.md +0 -83
  45. package/docs/NEXTJS-SETUP-COMPLETE.md +0 -795
  46. package/docs/NEXTJS-WEBPACK-WARNINGS.md +0 -267
  47. package/docs/NEXTJS-WRAPPER-APPROACH.md +0 -414
  48. package/docs/NUXT-GUIDE.md +0 -173
  49. package/docs/QUICKSTART-BODY-CAPTURE.md +0 -293
  50. package/docs/REDACTION-EXAMPLES.md +0 -484
  51. package/docs/REQUEST-BODY-CAPTURE.md +0 -587
  52. package/docs/SOLUTION-SUMMARY.md +0 -312
  53. package/docs/VERCEL-OTEL-MIGRATION.md +0 -255
  54. package/examples/README.md +0 -265
  55. package/examples/express-with-logging.js +0 -137
  56. package/examples/instrumentation-with-auto-capture.ts +0 -41
  57. package/examples/next.config.js +0 -37
  58. package/examples/nextjs-api-route-with-body-capture.ts +0 -54
  59. package/examples/nextjs-env-example.txt +0 -32
  60. package/examples/nextjs-instrumentation.js +0 -36
  61. package/examples/nextjs-instrumentation.ts +0 -36
  62. package/examples/nextjs-middleware.js +0 -37
  63. package/examples/nextjs-middleware.ts +0 -37
  64. package/examples/nextjs-with-logging-example.md +0 -301
  65. package/examples/nextjs-with-options.ts +0 -36
  66. package/examples/test-nextjs-setup.js +0 -70
  67. package/postinstall.js +0 -296
@@ -1,440 +0,0 @@
1
- # SecureNow Firewall — Automatic IP Blocking for Node.js
2
-
3
- Block malicious IPs at your application layer with zero code changes. The firewall syncs your SecureNow blocklist and enforces it across up to four network layers — from HTTP 403 responses all the way down to kernel-level packet drops and cloud-edge WAF rules.
4
-
5
- ---
6
-
7
- ## How It Works
8
-
9
- ```
10
- Internet Traffic
11
-
12
-
13
- ┌──────────────────────────┐
14
- │ Layer 4: Cloud/Edge WAF │ Blocked at CDN (Cloudflare, AWS WAF, GCP Cloud Armor)
15
- └──────────┬───────────────┘
16
-
17
- ┌──────────────────────────┐
18
- │ Layer 3: OS Firewall │ Dropped at kernel (iptables/nftables)
19
- └──────────┬───────────────┘
20
-
21
- ┌──────────────────────────┐
22
- │ Layer 2: TCP Socket │ socket.destroy() — zero bytes sent back
23
- └──────────┬───────────────┘
24
-
25
- ┌──────────────────────────┐
26
- │ Layer 1: HTTP Handler │ 403 Forbidden JSON response
27
- └──────────┬───────────────┘
28
-
29
- Your App
30
- ```
31
-
32
- All layers share the same in-memory blocklist, synced from the SecureNow API using a version-based protocol. Layer 1 (HTTP) is always active. Layers 2-4 are opt-in via environment variables.
33
-
34
- **Sync protocol:**
35
- - A lightweight version check runs every 10 seconds (uses ETag/304 -- no data transferred when unchanged)
36
- - Full blocklist sync only when the version changes, or every 5 minutes as a safety net
37
- - Changes propagate to all running instances in 10-15 seconds
38
- - Exponential backoff with jitter when the API is temporarily unreachable
39
- - Automatic localhost fallback when API is co-located (ECONNREFUSED triggers retry on `http://localhost:4000`)
40
-
41
- ---
42
-
43
- ## Quick Start
44
-
45
- ### 1. Get an API Key
46
-
47
- Two ways to get the firewall wired up — pick whichever fits:
48
-
49
- ```bash
50
- # (a) Zero-config (v7.4+): run login, pick/create an app, and connect.
51
- # The selected app's firewall toggle is enabled automatically.
52
- # The dashboard mints a key scoped firewall:read + blocklist:read + allowlist:read
53
- # and the CLI writes it to .securenow/credentials.json. No further config needed.
54
- npx securenow login
55
-
56
- # (b) Already have a key? Drop it into the credentials file directly:
57
- npx securenow api-key set snk_live_abc123...
58
-
59
- # View your firewall status and API key source
60
- npx securenow firewall status
61
- ```
62
-
63
- Or create an API key from the dashboard: **Settings → API Keys → Create Key** with the `firewall:read` scope.
64
-
65
- ### 2. Add the Key to Your Environment (optional)
66
-
67
- If you used `securenow login` or `securenow api-key set` above, you can **skip this step** — the SDK reads the key from `.securenow/credentials.json` at boot. Env vars are still supported for CI / Docker / prod:
68
-
69
- ```bash
70
- # .env
71
- SECURENOW_API_KEY=snk_live_abc123...
72
- ```
73
-
74
- ### 3. Start Your App
75
-
76
- ```bash
77
- node -r securenow/register app.js
78
- ```
79
-
80
- That's it. The firewall auto-activates as soon as a valid `snk_live_...` key is available (env var or credentials file). You'll see:
81
-
82
- ```
83
- [securenow] Firewall: ENABLED
84
- [securenow] Firewall: Layer 1 (HTTP 403) active
85
- [securenow] Firewall: Layer 2 (TCP drop) disabled (set SECURENOW_FIREWALL_TCP=1)
86
- [securenow] Firewall: Layer 3 (iptables) disabled (set SECURENOW_FIREWALL_IPTABLES=1)
87
- [securenow] Firewall: Layer 4 (Cloud WAF) disabled (set SECURENOW_FIREWALL_CLOUD=cloudflare|aws|gcp)
88
- [securenow] Firewall: synced 142 blocked IPs (138 exact + 4 CIDR ranges)
89
- ```
90
-
91
- ### Firewall-Only Mode (No Tracing)
92
-
93
- If you only need IP blocking without OpenTelemetry tracing:
94
-
95
- ```bash
96
- node -r securenow/firewall-only app.js
97
- ```
98
-
99
- This loads only the firewall with zero OTel dependencies. No `serverExternalPackages`, no `instrumentation.js`, no tracing overhead. Set `SECURENOW_API_KEY` in your environment and you're done.
100
-
101
- ---
102
-
103
- ## Layers In Detail
104
-
105
- ### Layer 1: HTTP Handler (default — always on)
106
-
107
- Intercepts every incoming HTTP/HTTPS request. Resolves the real client IP (respects `X-Forwarded-For` from trusted proxies), checks against the blocklist, and returns a 403 JSON response if blocked.
108
-
109
- ```json
110
- { "error": "Forbidden" }
111
- ```
112
-
113
- Works with every framework: Express, Fastify, Next.js, NestJS, Koa, Hapi, raw `http.createServer`, etc.
114
-
115
- **Customize the status code:**
116
-
117
- ```bash
118
- SECURENOW_FIREWALL_STATUS_CODE=429
119
- ```
120
-
121
- ### Layer 2: TCP Socket (`SECURENOW_FIREWALL_TCP=1`)
122
-
123
- Destroys the TCP connection before HTTP parsing starts. Zero bytes sent back to the attacker — they see a connection reset, not a response.
124
-
125
- ```bash
126
- SECURENOW_FIREWALL_TCP=1
127
- ```
128
-
129
- **Caveat:** TCP-level only sees the direct connection IP (no proxy headers). Connections from known proxy IPs are let through to Layer 1 for proper header-based resolution. Most effective for direct-to-server deployments.
130
-
131
- ### Layer 3: OS Firewall (`SECURENOW_FIREWALL_IPTABLES=1`)
132
-
133
- Manages a dedicated `SECURENOW_BLOCK` iptables/nftables chain. True kernel-level `DROP` — packets never reach Node.js.
134
-
135
- ```bash
136
- SECURENOW_FIREWALL_IPTABLES=1
137
- ```
138
-
139
- **Requirements:**
140
- - Linux only (skips gracefully on macOS/Windows)
141
- - Requires `root` or `CAP_NET_ADMIN` capability
142
- - Auto-detects nftables vs iptables
143
- - Dedicated chain — never touches your existing rules
144
- - Max 10,000 rules (configurable)
145
- - Full cleanup on process shutdown (SIGINT/SIGTERM)
146
-
147
- ### Layer 4: Cloud/Edge WAF (`SECURENOW_FIREWALL_CLOUD=<provider>`)
148
-
149
- Pushes the blocklist to your cloud WAF. Traffic is blocked at the CDN edge before it reaches your server.
150
-
151
- #### Cloudflare
152
-
153
- ```bash
154
- SECURENOW_FIREWALL_CLOUD=cloudflare
155
- CLOUDFLARE_API_TOKEN=your-token
156
- CLOUDFLARE_ACCOUNT_ID=your-account-id
157
- ```
158
-
159
- Creates/updates an IP List named `securenow-blocklist` with a WAF custom rule.
160
-
161
- #### AWS WAF
162
-
163
- ```bash
164
- SECURENOW_FIREWALL_CLOUD=aws
165
- AWS_WAF_IP_SET_ID=your-ip-set-id
166
- AWS_WAF_IP_SET_NAME=securenow-blocklist # optional, default
167
- AWS_WAF_SCOPE=REGIONAL # or CLOUDFRONT
168
- ```
169
-
170
- Requires `@aws-sdk/client-wafv2` installed as a peer dependency:
171
-
172
- ```bash
173
- npm install @aws-sdk/client-wafv2
174
- ```
175
-
176
- #### GCP Cloud Armor
177
-
178
- ```bash
179
- SECURENOW_FIREWALL_CLOUD=gcp
180
- GCP_PROJECT_ID=your-project
181
- GCP_SECURITY_POLICY=your-policy-name
182
- ```
183
-
184
- Requires `@google-cloud/compute` installed as a peer dependency:
185
-
186
- ```bash
187
- npm install @google-cloud/compute
188
- ```
189
-
190
- #### Dry-Run Mode
191
-
192
- Test cloud pushes without applying changes:
193
-
194
- ```bash
195
- SECURENOW_FIREWALL_CLOUD_DRY_RUN=1
196
- ```
197
-
198
- ---
199
-
200
- ## Environment Variables Reference
201
-
202
- | Variable | Default | Description |
203
- |----------|---------|-------------|
204
- | `SECURENOW_API_KEY` | *(from creds file)* | API key with `firewall:read` scope. Since v7.1.0 the firewall also reads this from `.securenow/credentials.json` (written by `securenow login` or `securenow api-key set`), so this env var is optional. The env var only wins if it starts with `snk_live_`; otherwise the credentials file is used. |
205
- | `SECURENOW_API_URL` | `https://api.securenow.ai` | API base URL. Auto-fallback to `http://localhost:4000` on ECONNREFUSED. |
206
- | `SECURENOW_FIREWALL_VERSION_INTERVAL` | `10` | Seconds between version checks (lightweight ETag-based) |
207
- | `SECURENOW_FIREWALL_SYNC_INTERVAL` | `300` | Full blocklist refresh interval in seconds (safety net) |
208
- | `SECURENOW_FIREWALL_FAIL_MODE` | `open` | `open` = allow when list unavailable; `closed` = block all |
209
- | `SECURENOW_FIREWALL_STATUS_CODE` | `403` | HTTP status code for blocked requests (Layer 1) |
210
- | `SECURENOW_FIREWALL_LOG` | `1` | Log blocked requests to console (`0` to silence) |
211
- | `SECURENOW_FIREWALL_TCP` | `0` | Enable Layer 2 TCP blocking |
212
- | `SECURENOW_FIREWALL_IPTABLES` | `0` | Enable Layer 3 iptables/nftables blocking |
213
- | `SECURENOW_FIREWALL_CLOUD` | *(none)* | Cloud WAF provider: `cloudflare`, `aws`, or `gcp` |
214
- | `SECURENOW_FIREWALL_CLOUD_DRY_RUN` | `0` | Log cloud pushes without applying |
215
- | `SECURENOW_TRUSTED_PROXIES` | *(none)* | Comma-separated trusted proxy IPs |
216
-
217
- ---
218
-
219
- ## Framework Examples
220
-
221
- ### Express.js
222
-
223
- ```bash
224
- # .env
225
- SECURENOW_APPID=my-express-app
226
- SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
227
- SECURENOW_API_KEY=snk_live_abc123...
228
- ```
229
-
230
- ```bash
231
- node -r securenow/register app.js
232
- ```
233
-
234
- No code changes needed. The firewall patches `http.createServer` before Express starts.
235
-
236
- ### Next.js
237
-
238
- ```bash
239
- # .env.local
240
- SECURENOW_APPID=my-nextjs-app
241
- SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
242
- SECURENOW_API_KEY=snk_live_abc123...
243
- ```
244
-
245
- ```javascript
246
- // next.config.js
247
- const { withSecureNow } = require('securenow/nextjs-webpack-config');
248
- module.exports = withSecureNow({ /* your config */ });
249
- ```
250
-
251
- ```typescript
252
- // instrumentation.ts
253
- export async function register() {
254
- if (process.env.NEXT_RUNTIME === 'nodejs') {
255
- const { registerSecureNow } = require('securenow/nextjs');
256
- registerSecureNow();
257
- }
258
- }
259
- ```
260
-
261
- The firewall initializes independently from OpenTelemetry -- it works even if tracing setup encounters an error.
262
-
263
- ### PM2 Cluster
264
-
265
- ```javascript
266
- // ecosystem.config.cjs
267
- module.exports = {
268
- apps: [{
269
- name: 'my-app',
270
- script: './app.js',
271
- instances: 4,
272
- node_args: '-r securenow/register',
273
- env: {
274
- SECURENOW_APPID: 'my-app',
275
- SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
276
- SECURENOW_API_KEY: 'snk_live_abc123...',
277
- SECURENOW_NO_UUID: '1',
278
- SECURENOW_FIREWALL_TCP: '1',
279
- }
280
- }]
281
- };
282
- ```
283
-
284
- ### Docker
285
-
286
- ```dockerfile
287
- ENV SECURENOW_APPID=my-app
288
- ENV SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
289
- ENV SECURENOW_API_KEY=snk_live_abc123...
290
- ENV SECURENOW_FIREWALL_TCP=1
291
-
292
- CMD ["node", "-r", "securenow/register", "app.js"]
293
- ```
294
-
295
- ---
296
-
297
- ## CLI Commands
298
-
299
- ### Check Firewall Status
300
-
301
- ```bash
302
- npx securenow firewall status
303
- ```
304
-
305
- Shows: enabled/disabled, active layers, last sync time, blocked IP count, and API key info.
306
-
307
- ### Test an IP
308
-
309
- ```bash
310
- npx securenow firewall test-ip 203.0.113.42
311
- ```
312
-
313
- Check whether a specific IP would be blocked by the current blocklist.
314
-
315
- ### Manage the Blocklist
316
-
317
- ```bash
318
- # List blocked IPs
319
- npx securenow blocklist
320
-
321
- # Block an IP
322
- npx securenow blocklist add 203.0.113.42 --reason "Brute force"
323
-
324
- # Unblock
325
- npx securenow blocklist remove <id>
326
-
327
- # Statistics
328
- npx securenow blocklist stats
329
- ```
330
-
331
- Changes take effect on the next version check (default every 10 seconds). Trusted IP changes also trigger immediate cache invalidation on the API side.
332
-
333
- ---
334
-
335
- ## Security Considerations
336
-
337
- ### Fail-Open vs Fail-Closed
338
-
339
- By default, the firewall operates in **fail-open** mode: if the API is unreachable, all traffic is allowed. This prevents the firewall from accidentally blocking legitimate traffic due to a network issue.
340
-
341
- For high-security environments, set `SECURENOW_FIREWALL_FAIL_MODE=closed` to block all traffic when the blocklist is unavailable.
342
-
343
- ### IP Resolution
344
-
345
- The firewall uses the same trusted-proxy-aware IP resolution as SecureNow tracing:
346
-
347
- - Only reads `X-Forwarded-For` / `X-Real-IP` when the direct connection comes from a private/trusted IP
348
- - Walks the header chain from right to left to find the first non-proxy IP
349
- - Configure additional trusted proxies via `SECURENOW_TRUSTED_PROXIES`
350
-
351
- ### API Key Security
352
-
353
- - The firewall API key only needs the `firewall:read` scope
354
- - Store it in environment variables or `.env` — never commit it to source control
355
- - The key is hashed (SHA-256) on the server — SecureNow never stores the plaintext
356
-
357
- ### Sync Architecture
358
-
359
- The SDK uses a unified sync endpoint (`/firewall/sync`) that combines version checking and data fetching into a single request:
360
-
361
- 1. **One request per poll** — The SDK sends its current blocklist and allowlist versions. The API responds with version info and only includes full IP lists for lists that have changed.
362
- 2. **HTTP Keep-Alive** — TCP connections are reused across polls. TLS handshake happens once; subsequent requests reuse the socket (~5-10ms vs ~100-200ms per request).
363
- 3. **Automatic fallback** — If the unified endpoint is not available (older API), the SDK falls back to legacy separate endpoints.
364
-
365
- ### Circuit Breaker & Back-Pressure
366
-
367
- - **Circuit breaker** — After 5 consecutive errors, the SDK pauses all polling for 2 minutes. After cooldown, a single probe is sent. If it succeeds, normal polling resumes.
368
- - **In-flight guard** — Only one poll can be in-flight at a time. If the API is slow, the next scheduled poll is skipped.
369
- - **429 Retry-After** — When the API returns HTTP 429, all polling pauses for the `Retry-After` duration.
370
- - **Exponential backoff** — Poll interval doubles on each consecutive error (10s → 20s → 40s → 80s, capped at 120s).
371
-
372
- ### Cleanup on Shutdown
373
-
374
- All layers clean up on process exit (SIGINT/SIGTERM):
375
- - Layer 1: restores original `http.createServer`
376
- - Layer 2: restores original `net.Server.prototype.listen`
377
- - Layer 3: removes the `SECURENOW_BLOCK` iptables/nftables chain
378
- - Layer 4: no cleanup needed (cloud rules persist intentionally)
379
-
380
- ---
381
-
382
- ## Troubleshooting
383
-
384
- ### Firewall Not Activating
385
-
386
- **Check 1:** Is `SECURENOW_API_KEY` set?
387
-
388
- ```bash
389
- echo $SECURENOW_API_KEY
390
- ```
391
-
392
- **Check 2:** Is the firewall disabled in SecureNow config or dashboard?
393
-
394
- ```bash
395
- npx securenow env
396
- npx securenow firewall apps
397
- ```
398
-
399
- The local SDK switch is `config.firewall.enabled` in `.securenow/credentials.json`. The runtime dashboard toggle is per app/environment.
400
-
401
- **Check 3:** Check the startup log for sync errors:
402
-
403
- ```
404
- [securenow] Firewall: initial sync failed: API returned 401
405
- ```
406
-
407
- This usually means the API key is invalid or missing the `firewall:read` scope.
408
-
409
- ### IPs Not Being Blocked
410
-
411
- **Check 1:** Is the IP actually in your blocklist?
412
-
413
- ```bash
414
- npx securenow blocklist
415
- npx securenow firewall test-ip 1.2.3.4
416
- ```
417
-
418
- **Check 2:** Are you behind a proxy? The firewall needs to see the real client IP. Set `SECURENOW_TRUSTED_PROXIES` to your proxy's IP.
419
-
420
- **Check 3:** Wait 10-15 seconds for version-based propagation. The version check interval defaults to 10 seconds.
421
-
422
- **Check 4:** Using PM2? Make sure `node_args: '-r securenow/register'` is in your `ecosystem.config.cjs`. Without it, PM2 restarts skip the SDK entirely.
423
-
424
- ### iptables Layer Not Working
425
-
426
- - Must be on Linux
427
- - Must run as root or with `CAP_NET_ADMIN`
428
- - Check: `iptables -L SECURENOW_BLOCK` (should show the chain)
429
-
430
- ---
431
-
432
- ## Related Documentation
433
-
434
- - [API Keys Guide](./API-KEYS-GUIDE.md) — Creating and managing API keys
435
- - [Environment Variables Reference](./ENVIRONMENT-VARIABLES.md) — All configuration options
436
- - [All Frameworks Quick Start](./ALL-FRAMEWORKS-QUICKSTART.md) — Framework setup guides
437
- - [Automatic IP Capture](./AUTOMATIC-IP-CAPTURE.md) — How client IPs are resolved
438
- # Current setup note
439
-
440
- Use `.securenow/credentials.json` for local and production. `npx securenow login` writes the firewall key locally; `npx securenow credentials runtime --env production` creates the tokenless production file to mount/copy as `.securenow/credentials.json`. Env-var examples in this older guide are legacy fallback snippets.