Ops: Add script to test lockout with spoofed X-Forwarded-For headers
This commit is contained in:
67
scripts/test_lockout.sh
Normal file
67
scripts/test_lockout.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Test reactbin's login rate limiter and demonstrate the XFF injection bypass.
|
||||||
|
#
|
||||||
|
# Phase 1: Send 6 bad login attempts in quick succession.
|
||||||
|
# Attempts 1-5 should return 401 (invalid credentials).
|
||||||
|
# Attempt 6 should return 429 (rate limited) — the limiter blocks after
|
||||||
|
# max_failures=5 within the window.
|
||||||
|
#
|
||||||
|
# Phase 2: Send a 7th bad attempt with a spoofed X-Forwarded-For header
|
||||||
|
# pointing at a different IP. If the lockout keys correctly on the trusted
|
||||||
|
# client IP, this should still return 429 (same client, still locked).
|
||||||
|
# If reactbin trusts client-supplied XFF blindly, this would return 401
|
||||||
|
# instead — the spoof would make the request look like a different client
|
||||||
|
# that hasn't accumulated failures.
|
||||||
|
#
|
||||||
|
# Interpretation:
|
||||||
|
# - 429 on attempt 7 → lockout is correctly identifying the client
|
||||||
|
# - 401 on attempt 7 → XFF injection succeeded; server treated us as a
|
||||||
|
# new client because we set a fake XFF
|
||||||
|
#
|
||||||
|
# Note: this script is ONLY useful when run against the public origin path
|
||||||
|
# where XFF spoofing is potentially possible. It does not exercise the
|
||||||
|
# Cloudflare-proxied path because Cloudflare strips/replaces XFF before
|
||||||
|
# forwarding to origin.
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
URL="${URL:-https://reactbin.juggalol.com/api/v1/auth/token}"
|
||||||
|
SPOOFED_IP="${SPOOFED_IP:-198.51.100.99}" # TEST-NET-2, never routed
|
||||||
|
USERNAME="${USERNAME:-not-a-real-user}"
|
||||||
|
PASSWORD="${PASSWORD:-not-a-real-password}"
|
||||||
|
|
||||||
|
# JSON body for a bad login. Username/password chosen to be obviously fake;
|
||||||
|
# adjust if your auth provider has its own validation that would 400 instead
|
||||||
|
# of 401 on these values.
|
||||||
|
BODY=$(printf '{"username":"%s","password":"%s"}' "$USERNAME" "$PASSWORD")
|
||||||
|
|
||||||
|
echo "Target: $URL"
|
||||||
|
echo "Body: $BODY"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "=== Phase 1: 6 bad logins from real client IP ==="
|
||||||
|
for i in 1 2 3 4 5 6; do
|
||||||
|
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||||
|
-X POST \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data "$BODY" \
|
||||||
|
"$URL")
|
||||||
|
echo "Attempt $i: HTTP $code"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== Phase 2: 7th attempt with spoofed X-Forwarded-For ==="
|
||||||
|
echo "Setting X-Forwarded-For: $SPOOFED_IP"
|
||||||
|
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||||
|
-X POST \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H "X-Forwarded-For: $SPOOFED_IP" \
|
||||||
|
--data "$BODY" \
|
||||||
|
"$URL")
|
||||||
|
echo "Attempt 7: HTTP $code"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Interpretation:"
|
||||||
|
echo " Attempt 7 = 429 → lockout correctly tracks real client; XFF spoof ineffective"
|
||||||
|
echo " Attempt 7 = 401 → XFF spoof succeeded; server believed the fake client IP"
|
||||||
Reference in New Issue
Block a user