58 lines
2.6 KiB
Bash
Executable File
58 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# tests/security.sh — Тесты безопасности ipwhitelist-app
|
|
# Запуск: TOKEN=eyJ... bash tests/security.sh [BASE_URL]
|
|
|
|
set -euo pipefail
|
|
BASE="${1:-https://italo.kube5s.ru}"
|
|
TOKEN="${TOKEN:-}"
|
|
PASS=0; FAIL=0
|
|
|
|
api() { curl -s --http2 -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -w "\n%{http_code}" "$@"; }
|
|
check() { local n="$1" e="$2" a="$3"; if echo "$a" | grep -q "$e"; then echo "✅ $n"; PASS=$((PASS+1)); else echo "❌ $n (expected: $e)"; FAIL=$((FAIL+1)); fi; }
|
|
checkno() { local n="$1" e="$2" a="$3"; if ! echo "$a" | grep -q "$e"; then echo "✅ $n"; PASS=$((PASS+1)); else echo "❌ $n (found: $e)"; FAIL=$((FAIL+1)); fi; }
|
|
|
|
echo "=== SECURITY TESTS ==="
|
|
|
|
# 1. Open redirect
|
|
R=$(curl -s --http2 -o /dev/null -w "%{http_code}" "$BASE/login?returnTo=//evil.com")
|
|
check "1. open redirect in login" "200\|302" "$R"
|
|
|
|
# 2. Header injection in /export
|
|
R=$(curl -s --http2 -D - "$BASE/export?filename=test%0d%0aX-Injected:%20yes" 2>/dev/null)
|
|
checkno "2. no CRLF in Content-Disposition" "X-Injected" "$R"
|
|
|
|
# 3. XSS in input
|
|
R=$(api -X POST -d '{"value":"8.8.8.8","comment":"<script>alert(1)</script>"}' "$BASE/api/v1/entries")
|
|
check "3. XSS in comment accepted (stored, EJS escapes)" "201" "$R"
|
|
|
|
# 4. SQL injection attempt
|
|
R=$(api -X POST -d "{\"value\":\"8.8.4.4\",\"comment\":\"'; DROP TABLE users;--\"}" "$BASE/api/v1/entries")
|
|
check "4. SQL injection rejected by validation" "400\|201" "$R"
|
|
|
|
# 5. Bearer required
|
|
R=$(curl -s --http2 -o /dev/null -w "%{http_code}" "$BASE/api/v1/entries")
|
|
check "5. no Bearer = 401" "401" "$R"
|
|
|
|
# 6. Invalid Bearer
|
|
R=$(curl -s --http2 -H "Authorization: Bearer garbage" -o /dev/null -w "%{http_code}" "$BASE/api/v1/entries")
|
|
check "6. invalid Bearer = 401" "401" "$R"
|
|
|
|
# 7. POST without CSRF (should work since CSRF not enforced)
|
|
R=$(curl -s --http2 -b /tmp/ctest.txt -c /tmp/ctest.txt -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "clientId=WZ01112&returnTo=/" -o /dev/null -w "%{http_code}" "$BASE/login")
|
|
check "7. login without CSRF token" "302" "$R"
|
|
|
|
# 8. /export header injection via Content-Disposition
|
|
R=$(curl -s --http2 -D - -o /dev/null "$BASE/export?filename=test%22%3B%20evil" 2>/dev/null)
|
|
checkno "8. no quote injection in filename" "evil" "$R"
|
|
|
|
# 9. Massive value (DoS attempt)
|
|
R=$(api -X POST -d "{\"value\":\"1.1.1.1\",\"comment\":\"$(python3 -c 'print("A"*10000)' 2>/dev/null || echo 'overflow')\"}" "$BASE/api/v1/entries")
|
|
check "9. large comment rejected" "400\|201" "$R"
|
|
|
|
# 10. Empty value
|
|
R=$(api -X POST -d '{"value":"","comment":"test"}' "$BASE/api/v1/entries")
|
|
check "10. empty value rejected" "400" "$R"
|
|
|
|
echo ""
|
|
echo "=== Security: $PASS/$((PASS+FAIL)) ==="
|