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