-
Notifications
You must be signed in to change notification settings - Fork 232
feat: add security load test and regression tooling #462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
59a41ec
89202b1
35eaa50
84792e4
b30798e
8d2c6f9
00b25e6
1841d8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,196 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env node | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * security-load-test.js | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * A generalized load testing and security emulation tool for Nostream. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Simulates a combined Slowloris (Zombie) attack and an Event Flood attack. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Features: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 1. Zombie Connections: Opens connections, subscibes, and silences pongs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
cameri marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 2. Active Spammer: Generates and publishes valid NOSTR events (signed via secp256k1). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Usage: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * node scripts/security-load-test.js [--url ws://localhost:8008] [--zombies 5000] [--spam-rate 100] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Alternate (via npm): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * npm run test:load -- --zombies 5000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const WebSocket = require('ws'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const crypto = require('crypto'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const secp256k1 = require('@noble/secp256k1'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ── CLI Args ───────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const args = process.argv.slice(2).reduce((acc, arg, i, arr) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
cameri marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (arg.startsWith('--')) acc[arg.slice(2)] = arr[i + 1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return acc; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, {}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const RELAY_URL = args.url || 'ws://localhost:8008'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const TOTAL_ZOMBIES = parseInt(args.zombies || '5000', 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SPAM_RATE = parseInt(args['spam-rate'] || '0', 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const args = process.argv.slice(2).reduce((acc, arg, i, arr) => { | |
| if (arg.startsWith('--')) acc[arg.slice(2)] = arr[i + 1]; | |
| return acc; | |
| }, {}); | |
| const RELAY_URL = args.url || 'ws://localhost:8008'; | |
| const TOTAL_ZOMBIES = parseInt(args.zombies || '5000', 10); | |
| const SPAM_RATE = parseInt(args['spam-rate'] || '0', 10); | |
| function parseCliArgs(argv) { | |
| const acc = {}; | |
| for (let i = 0; i < argv.length; i++) { | |
| const arg = argv[i]; | |
| if (!arg.startsWith('--')) continue; | |
| const key = arg.slice(2); | |
| const value = argv[i + 1]; | |
| if (value === undefined || value.startsWith('--')) { | |
| console.error(`Missing value for --${key}`); | |
| process.exit(1); | |
| } | |
| acc[key] = value; | |
| i++; | |
| } | |
| return acc; | |
| } | |
| function parseIntegerArg(value, defaultValue, flagName) { | |
| if (value === undefined) return defaultValue; | |
| const parsed = Number.parseInt(value, 10); | |
| if (Number.isNaN(parsed)) { | |
| console.error(`Invalid value for --${flagName}: ${value}. Expected an integer.`); | |
| process.exit(1); | |
| } | |
| return parsed; | |
| } | |
| const args = parseCliArgs(process.argv.slice(2)); | |
| const RELAY_URL = args.url || 'ws://localhost:8008'; | |
| const TOTAL_ZOMBIES = parseIntegerArg(args.zombies, 5000, 'zombies'); | |
| const SPAM_RATE = parseIntegerArg(args['spam-rate'], 0, 'spam-rate'); |
Uh oh!
There was an error while loading. Please reload this page.