A Python command-line tool for performing basic load testing and security stress checks on any web server. This project is intended for educational purposes and safe testing on your own servers.
Important: Do not run this tool on servers you do not own or have explicit permission to test. Running high-concurrency requests against third-party sites can be illegal and considered a DDoS attack.
Sending high‑concurrency or repeated requests may be interpreted as DDoS behavior and can:
- trigger security filters
- cause temporary IP bans
- result in legal action
Only use this tool on:
- servers you own
- servers you manage
- servers where you have explicit permission
This script helps you evaluate:
- High‑concurrency request handling
- Response latency
- Request throughput
- Stability under stress
- It can help verify whether your server:
- triggers rate‑limit protection
- blocks abusive behavior
- activates firewall rules (e.g., fail2ban, CSF, Cloudflare, Nginx limits)
- identifies suspicious patterns
Note
- The tool cannot bypass protections.
- If your server firewall blocks your IP during testing, that’s expected — your server is doing its job.
- Clone or pull this repository to your local machine.
git clone https://github.com/smile675/server-security-test.git cd server-security-test - Create a Python virtual environment according to your OS requirements and activate it.
# Windows (PowerShell) python -m venv venv .\venv\Scripts\Activate.ps1
# Windows (Command Prompt) python -m venv venv venv\Scripts\activate.bat
# Linux / macOS python3 -m venv venv source venv/bin/activate
- Install necessary packages
pip install -r requirements.txt
- Run each test individually using Python.
- If your server successfully protects against a test (e.g., triggers rate-limiting or blocks your IP), wait a few minutes before running another test to avoid being temporarily blocked.
The following tests are available. We will be keep adding more tests as we progress.
Description: A Python command-line tool that evaluates how a server responds to high-frequency requests. It detects whether the server has protections such as rate-limiting, firewall/WAF rules, or throttling mechanisms in place.
How it Works:
- Sends multiple concurrent GET requests to a target URL.
- Tracks response status codes (200, 403, 429, 503, etc.) and request latency.
- Checks response bodies for keywords indicating blocks or protection messages (e.g., “rate limit”, “temporarily blocked”, “access denied”).
- Provides a summary of request success/failure, latency statistics, and detected block messages.
- Gives a final verdict on whether the server shows signs of protection against high-rate/flood attacks.
Expected Results:
- HTTP 429 (rate-limiting), 403 (WAF/firewall), or 503 (overload protection) may appear.
- Block/protection keywords detected in response body.
- Latency spikes for some requests.
- Final verdict: Your server HAS some protection against rapid/flood attacks.
- Most or all requests return HTTP 200.
- No block keywords detected.
- Latency remains consistently low.
Final verdict: Your server DOES NOT appear to protect against high-rate requests. It may be vulnerable to basic request-flood attacks.
How to Run the test
python tests/flood_resistance_test.py https://yourdomain.com --concurrency 50 --duration 20Description: A Python command-line tool that simulates slowloris-style attacks, where clients intentionally send requests with delayed/slow body transmission. It evaluates whether the server has timeout protections and can handle resource exhaustion from stalled connections.
How it Works:
- Sends multiple concurrent POST requests with intentionally slow payload transmission.
- Chunks the request body and delays between chunks to keep connections open longer than normal.
- Tracks response status codes, connection resets, and timeout errors.
- Checks response bodies for timeout-related keywords.
- Provides a summary of timeouts, connection resets, and latency patterns.
- Gives a final verdict on whether the server protects against slow client attacks.
Expected Results:
- HTTP 408 (Request Timeout) or 504 (Gateway Timeout) responses.
- Connection resets when clients delay too long.
- Timeout keywords detected in response body.
- High latency followed by request failures.
- Final verdict: Your server HAS protection against slow client attacks.
- Most or all requests return HTTP 200 despite slow transmission.
- No connection resets or timeouts.
- Server continues to accept slow requests indefinitely.
- Final verdict: Your server DOES NOT appear to protect against slow client attacks. It may be vulnerable to slowloris or resource exhaustion attacks.
How to Run the test
python tests/slow_client_test.py https://yourdomain.com --concurrency 10 --duration 15 --delay 2.0Arguments:
--concurrency(int, default 10): Number of parallel slow clients--duration(int, default 10): Test duration in seconds--delay(float, default 2.0): Delay between payload chunks in seconds
Description: Simulates clients uploading very large request bodies to a target endpoint to verify whether the server enforces request size limits, times out, or closes connections during heavy uploads.
How it Works:
- Streams large POST bodies (configurable size per request) in small chunks to avoid allocating the entire payload in memory.
- Runs multiple parallel upload workers to increase load and exercise server/proxy limits.
- Tracks HTTP status codes, latencies, connection resets, timeouts, and looks for common "payload too large" messages in responses.
- Produces a summary and a protection analysis (detects HTTP 413, resets, 502/503/504 gateway errors, and related behavior).
Expected Results:
- HTTP 413 (Payload Too Large) or explicit limit messages in responses.
- Connection resets during upload (server/proxy closes uploads it deems too large).
- Gateway errors/timeouts (502/503/504) if upstream refuses large uploads.
- Final verdict: Server enforces size limits or otherwise protects against large uploads.
- Most uploads complete successfully (HTTP 200 or similar).
- No explicit limit messages or connection resets.
- Final verdict: Server may accept arbitrarily large uploads — consider adding request size limits and proxy protections.
How to Run the test
python tests/large_payload_test.py https://yourdomain.comArguments:
--concurrency(int, default 5): Number of parallel upload workers--duration(int, default 30): Test duration in seconds--size-mb(float, default 21.0): Payload size per request in MB--chunk-size(int, default 65536): Upload chunk size in bytes
Description: Sends requests with malformed, oversized, or numerous header fields to discover header parsing and validation limits. The test helps detect whether front-end servers or WAFs properly limit header sizes and counts and whether malformed headers cause connection resets or parsing errors.
How it Works:
- Sends requests that exercise a range of header abuses: very long header values (e.g.,
User-Agent), extremely largeCookieheaders, many distinct headers, duplicated header values, and attempts at illegal header names. - Tracks HTTP status codes (400, 431, 403, etc.), latencies, connection resets, and client-side exceptions.
- Scans response bodies for common block or error messages (e.g., "Header Fields Too Large", "bad request").
- Produces a summary and a protection analysis indicating whether header limits or WAF protections are in effect.
Expected Results:
- HTTP 431 (Header Fields Too Large) or HTTP 400 for malformed headers.
- HTTP 403 if a WAF/firewall blocks requests.
- Connection resets or socket errors when the server/proxy rejects oversized headers.
- Final verdict: Server enforces header limits and resists header-based abuse.
- Most requests succeed (HTTP 200) even with oversized/duplicate headers.
- No header-specific error messages detected.
- Final verdict: Consider enforcing header size/count limits at the proxy (e.g., Nginx) or WAF.
How to Run the test
python tests/header_injection_test.py https://yourdomain.comArguments:
--concurrency(int, default 5): Parallel workers--duration(int, default 20): Test duration in seconds--max-header-kb(int, default 64): Approximate maximum header size to attempt (KB)--many-headers(int, default 200): Number of headers to send in the "many headers" case--duplicate-count(int, default 50): Number of duplicate values simulated (comma-separated simulation)
Description: Sends a curated set of benign-but-malicious-looking SQL injection payloads (via URL parameters and request bodies) to detect whether the server has input validation, WAF protections, or error-message leakage that indicates potential SQL injection vulnerability.
How it Works:
- Sends a list of recognizable SQL injection patterns (e.g.,
' OR '1'='1,UNION SELECT, boolean probes) as URL parameters. - Tracks HTTP status codes, latencies, and connection-level errors.
- Scans response bodies for:
- WAF keywords: "sql injection", "attack detected", "blocked", "403" (indicating WAF/protection).
- Database error keywords: "sql syntax", "table not found", "column not found", "postgresql", "mysql", etc. (indicating error leakage).
- Produces a summary and protection analysis.
Expected Results:
- HTTP 403 (WAF blocks malicious patterns).
- HTTP 400 (Server rejects suspicious input).
- No database error messages in responses (error suppression).
- Final verdict: Server has protections against SQL injection.
- Payloads accepted without rejection (HTTP 200).
- Database error messages leaked in responses (e.g., "SQL syntax error", "table not found").
- Final verdict: Review input validation, enable error suppression, and deploy WAF rules.
How to Run the test
python tests/sql_injection_test.py https://yourdomain.com/search Arguments:
url: Target URL (e.g.,https://yourdomain.com/search)--param(str, default "q"): Query parameter name to inject payloads into--concurrency(int, default 5): Parallel workers--duration(int, default 20): Test duration in seconds
Description: Sends intentionally malformed HTTP requests to validate the server's protocol-compliance and parser robustness. It tests the server's ability to handle missing CRLF sequences, invalid HTTP methods, wrong protocol versions, malformed chunk boundaries, and other HTTP grammar violations. The goal is to discover whether the server fails safely with graceful 4xx errors or if it crashes, hangs, or exhibits unexpected behavior.
How it Works:
- Sends a series of malformed HTTP requests with various violations (e.g.,
GET / HTTP/2.5, missing colons in headers, invalid chunked encoding, oversized Content-Length, null bytes, etc.). - Uses raw sockets to send requests directly (bypassing HTTP client libraries that may auto-correct).
- Tracks outcomes: HTTP responses (including status codes), connection resets, timeouts, connection refusals, and exceptions.
- Produces a summary and protection analysis based on observed behavior.
Expected Results:
- Malformed requests return HTTP 400 (Bad Request) or 405 (Method Not Allowed).
- Connection resets for egregiously malformed input (protection against parser exploits).
- No timeouts or server crashes.
- Final verdict: Server gracefully rejects malformed HTTP.
- Malformed requests accepted without error (HTTP 200).
- Server timeouts or hangs on certain patterns.
- HTTP 500 (Internal Server Error) responses.
- Unexplained connection resets or crashes.
- Final verdict: Server parser may be vulnerable to DoS or protocol confusion attacks.
How to Run the test
python tests/protocol_confusion_test.py yourdomain.comArguments:
host: Target hostname (e.g.,yourdomain.com)--port(int): Target port (default 443 if scheme is https)--scheme(str): Protocol scheme (httporhttps)--duration(int): Test duration in seconds
Description:
Sends requests with structurally invalid payloads and header/body mismatches (e.g., Content-Length not matching body size, chunked encoding errors, broken multipart boundaries) to verify whether the server properly validates request framing and returns safe error responses rather than exposing stack traces or leaking internal state.
How it Works:
- Generates a series of malformed requests with 13 different framing violation patterns (e.g.,
Content-Lengthsmaller than body, mismatchedContent-Length, chunked encoding with invalid chunks, broken multipart boundaries, conflictingTransfer-EncodingandContent-Lengthheaders). - Sends each malformed request and tracks HTTP status codes, latencies, and response content.
- Scans response bodies for error-leakage keywords (e.g., "traceback", "exception", "file not found", "module error", stack traces).
- Produces a summary and a protection analysis indicating whether the server safely handles malformed input.
Expected Results:
- HTTP 400 (Bad Request), 411 (Length Required), or 413 (Payload Too Large) for framing violations.
- Connection resets for protocol-level violations (expected defensive behavior).
- No stack traces, exception details, or internal error messages in responses.
- Final verdict: Server safely rejects malformed requests and suppresses error leakage.
- Malformed requests accepted (HTTP 200) without detection.
- Error messages, stack traces, or file paths visible in responses.
- No defensive connection resets or proper error responses.
- Final verdict: Server may expose internal details on malformed input; review error suppression and request validation.
How to Run the test
python tests/malformed_request_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.com)--concurrency(int): Number of parallel workers--duration(int): Test duration in seconds
Description: Exercises authentication endpoints with low-rate credential trials to detect whether the server has account lockout, rate-limiting, or captcha defenses. The test sends configurable username/password combinations at controlled rates and records HTTP 200/401/429 responses and any account lock notifications. This test is intentionally rate-limited by default and should never be used against third-party services.
How it Works:
- Sends credential trials (username/password pairs) to a target authentication endpoint at a controlled rate per worker.
- Uses a predefined list of common credentials (e.g.,
admin/password,root/123456,test/password) to simulate credential-guessing attacks. - Tracks HTTP status codes (200, 401, 403, 429, etc.), response times, and connection-level errors.
- Scans response bodies for defense indicators:
- Rate-limiting keywords: "rate limit", "too many", "throttle", "retry after"
- Account lock keywords: "locked", "disabled", "suspended", "blocked"
- Captcha indicators: "captcha", "human", "verify", "robot"
- Produces a summary and a protection verdict indicating whether the server defends against brute-force attacks.
Expected Results:
- HTTP 429 (Too Many Requests) responses indicating rate-limiting.
- HTTP 403 (Forbidden) or progressive rejection after multiple failed attempts.
- Account lock keywords or notifications in responses.
- Captcha challenges or human verification prompts detected.
- Final verdict: Server has brute-force protections in place.
- Repeated HTTP 401 (Unauthorized) responses without rate-limiting.
- HTTP 200 (success) responses accepted after multiple credential trials.
- No account lockout or rate-limiting observed.
- No captcha or human verification challenges.
- Final verdict: Server lacks brute-force defenses; add rate-limiting, account lockout, and/or captcha.
How to Run the test
python tests/auth_bruteforce_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.com)--auth-endpoint(str): Authentication endpoint path (e.g.,/login,/api/auth)--concurrency(int): Number of parallel brute-force workers--duration(int): Test duration in seconds--rate-limit-delay(float): Delay in seconds between each credential attempt (per worker)
Description:
Issues specially crafted path requests (e.g., ../, encoded traversal sequences) and requests for known sensitive files to check for filesystem access leaks or incorrect path normalization. The test verifies server and application-layer path sanitization and returns observations like 200 (sensitive file returned), 403 (forbidden), or 404 (not found). The test is non-destructive and should only request public or non-sensitive endpoints in practice.
How it Works:
- Generates a series of directory traversal payloads including basic traversal (
../), URL-encoded variants (%2e%2e%2f), double-encoded sequences, backslash attempts, null-byte injection, and Unicode encoding. - Also requests known sensitive files (e.g.,
/etc/passwd,/etc/shadow,.env,.git/config,web.config). - Sends GET requests with these payloads appended to a configurable base path and tracks HTTP status codes and response content.
- Scans response bodies for sensitive file indicators (e.g., "root:", "PATHEXT=", "<?php", "password", "apikey", "secret").
- Produces a summary and a protection verdict indicating whether the server properly validates and sanitizes paths.
Expected Results:
- HTTP 404 (Not Found) or HTTP 403 (Forbidden) for traversal attempts.
- No sensitive files or credentials returned (HTTP 200 with file content).
- Path normalization blocks encoded/obfuscated traversal attempts.
- No sensitive content indicators in responses.
- Final verdict: Server properly sanitizes paths and restricts filesystem access.
- HTTP 200 (success) responses with traversal payloads, potentially exposing files outside intended directory.
- Sensitive file content leaked (e.g.,
/etc/passwdcontents, environment variables, API keys). - Encoded or double-encoded traversal attempts bypassing basic filters.
- Final verdict: Implement strict path validation, sanitization, and access controls. Deploy WAF rules to block traversal patterns.
How to Run the test
python tests/directory_traversal_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.com)--base-path(str): Base path to append traversal payloads to (e.g.,/,/download,/api/files)--concurrency(int): Number of parallel workers--duration(int): Test duration in seconds
Description: Performs a range of TLS/SSL negotiation scenarios — different protocol versions, cipher suites, and certificate validation — to detect weak configurations and handshake robustness. The test checks whether the server properly rejects obsolete TLS versions (e.g., SSLv3, TLSv1.0, TLSv1.1), offers only strong ciphers, validates certificates properly, and handles handshake robustness without crashing.
How it Works:
- Tests multiple TLS/SSL protocol versions (SSLv3, TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3) to determine which are accepted.
- Attempts to negotiate weak cipher suites (RC4, DES, 3DES, MD5, NULL, EXPORT, aNULL, eNULL) and tracks acceptance/rejection.
- Validates certificate chain and presence; checks for certificate validity issues.
- Tracks successful handshakes with deprecated protocols or weak ciphers (signs of vulnerability).
- Produces a summary and protection verdict indicating TLS configuration strength.
Expected Results:
- Only TLSv1.2 and TLSv1.3 are accepted.
- Deprecated versions (SSLv3, TLSv1.0, TLSv1.1) are rejected.
- Weak ciphers are not negotiated.
- Valid certificate chain is present and validates correctly.
- Final verdict: TLS configuration meets modern security standards.
- Deprecated TLS versions (SSLv3, TLSv1.0, TLSv1.1) are accepted.
- Weak or export ciphers are negotiated.
- Certificate chain validation fails or no certificate present.
- Final verdict: Disable deprecated protocols, remove weak ciphers, and ensure valid certificate deployment.
How to Run the test
python tests/tls_handshake_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.com)
Description: Opens many concurrent WebSocket connections and/or sends high-frequency frames to test server support for real-time protocols. The test checks for connection limits, frame-dropping, server memory growth, and application-level backpressure handling. It is useful when the server hosts WebSocket or other persistent real-time services.
How it Works:
- Opens a configurable number of concurrent WebSocket connections to a target endpoint.
- Each connection sends a series of test frames with configurable delays between them.
- Tracks successful connection establishments, connection timeouts, connection refusals, and file descriptor exhaustion.
- Monitors frame transmission and reception; detects frame timeouts and connection closures during send.
- Calculates frame latency statistics and identifies frame-dropping or throttling behavior.
- Produces a summary and protection verdict indicating whether the server enforces resource limits.
Expected Results:
- Connection limits enforced (not all concurrent requests accepted).
- Frame dropping or throttling detected under load.
- Backpressure signals: connection closure, receive timeouts.
- Per-connection resource caps preventing memory exhaustion.
- Final verdict: Server has WebSocket resource protections.
- All connection attempts accepted (no connection limit).
- Frames transmitted and received without dropping.
- No throttling or backpressure observed.
- Potential for memory exhaustion with many concurrent connections.
- Final verdict: Add connection limits, frame rate limiting, and per-connection memory caps.
How to Run the test
python tests/websocket_flood_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.comorwss://yourdomain.com)--ws-path(str): WebSocket path (e.g.,/ws,/socket.io)--concurrency(int): Number of concurrent WebSocket connections--duration(int): Test duration in seconds--frame-delay(float): Delay in seconds between frames per connection
Description: Triggers server-side expensive operations (safe, non-destructive inputs that cause heavy processing) to see whether CPU-intensive requests are protected by rate limits or cost-based throttling. Examples include requests that cause expensive regexes, large data parsing, or deeply nested JSON/XML processing on the server. The test monitors response times, error patterns, and detection of server degradation under load.
How it Works:
- Generates a series of CPU-intensive payloads designed to trigger expensive server-side processing:
- Regex backtracking patterns (e.g.,
a*1000 +b, unbalanced parentheses) - Deeply nested JSON and XML structures
- Large string manipulation operations
- Large numeric string parsing
- Regex backtracking patterns (e.g.,
- Sends these payloads concurrently to a configurable endpoint.
- Tracks HTTP status codes, latencies, timeouts, rate-limit responses (429), and server errors (5xx).
- Scans response bodies for error/exception messages indicating server stress.
- Analyzes latency trends; if latency increases significantly over time, this indicates resource exhaustion or throttling.
- Produces a summary and protection verdict.
Expected Results:
- HTTP 429 (Too Many Requests) responses indicating rate-limiting.
- Response degradation: slow requests or timeouts indicating throttling.
- Latency increase over test duration (sign of exhaustion detection and protection).
- No unexpected server errors or crashes.
- Final verdict: Server protects against CPU exhaustion via rate-limiting or cost tracking.
- All requests processed without rate-limiting (no 429 responses).
- Consistent low latency maintained; no degradation under load.
- Server errors (5xx) or timeouts indicating crash risk.
- No error suppression; stack traces or internal details leaked.
- Final verdict: Add rate-limiting, CPU cost calculation, and graceful degradation.
How to Run the test
python tests/resource_exhaustion_cpu_test.py https://yourdomain.comArguments:
url: Target URL (e.g.,https://yourdomain.com)--endpoint(str): Endpoint to send CPU-intensive payloads to--concurrency(int): Number of parallel workers--duration(int): Test duration in seconds
If you would like to contribute to this project, please follow the Contribution Guide for instructions on how to contribute effectively.