fix: 0.0.0.0/8 → blocked ranges + bump 0.5.23

This commit is contained in:
2026-06-04 16:13:04 +03:00
parent 05c6920987
commit e9bd94cea3
4 changed files with 105 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ipwhitelist",
"version": "0.5.22",
"version": "0.5.23",
"description": "IP WhiteList microservice for cloud provider",
"main": "server.js",
"scripts": {
+1
View File
@@ -15,6 +15,7 @@ const BLOCKED_RANGES = [
'198.18.0.0/15',
'224.0.0.0/4',
'240.0.0.0/4',
'0.0.0.0/8',
'255.255.255.255/32',
];
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# tests/edge-cases.sh — Краевые случаи валидации CIDR
# Запуск: TOKEN=eyJ... bash tests/edge-cases.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, got: $(echo $a | tail -1 | head -c 80))"; FAIL=$((FAIL+1)); fi; }
echo "=== CIDR EDGE CASES ==="
# ── Валидные ──
check "1. /32" "201" "$(api -X POST -d '{"value":"8.8.8.8"}' "$BASE/api/v1/entries")"
check "2. /22" "201" "$(api -X POST -d '{"value":"8.8.8.0/22"}' "$BASE/api/v1/entries")"
check "3. нормализация хоста" "wasNormalized" "$(api -X POST -d '{"value":"8.8.8.10/24"}' "$BASE/api/v1/entries")"
# ── Невалидные маски ──
check "4. /21 слишком широко" "400" "$(api -X POST -d '{"value":"1.0.0.0/21"}' "$BASE/api/v1/entries")"
check "5. /33 невалидно" "400" "$(api -X POST -d '{"value":"1.1.1.1/33"}' "$BASE/api/v1/entries")"
check "6. /0" "400" "$(api -X POST -d '{"value":"0.0.0.0/0"}' "$BASE/api/v1/entries")"
# ── Серые адреса ──
check "7. 10.x" "400" "$(api -X POST -d '{"value":"10.0.0.1"}' "$BASE/api/v1/entries")"
check "8. 192.168.x" "400" "$(api -X POST -d '{"value":"192.168.1.1"}' "$BASE/api/v1/entries")"
check "9. 172.16.x" "400" "$(api -X POST -d '{"value":"172.16.0.1"}' "$BASE/api/v1/entries")"
check "10. 127.x loopback" "400" "$(api -X POST -d '{"value":"127.0.0.1"}' "$BASE/api/v1/entries")"
# ── IPv6 ──
check "11. IPv6" "400" "$(api -X POST -d '{"value":"::1"}' "$BASE/api/v1/entries")"
check "12. IPv6 full" "400" "$(api -X POST -d '{"value":"2001:db8::1"}' "$BASE/api/v1/entries")"
# ── Мусор ──
check "13. домен" "400" "$(api -X POST -d '{"value":"example.com"}' "$BASE/api/v1/entries")"
check "14. пусто" "400" "$(api -X POST -d '{"value":""}' "$BASE/api/v1/entries")"
check "15. пробелы" "400" "$(api -X POST -d '{"value":" "}' "$BASE/api/v1/entries")"
# ── Специальные ──
check "16. multicast" "400" "$(api -X POST -d '{"value":"224.0.0.1"}' "$BASE/api/v1/entries")"
check "17. broadcast" "400" "$(api -X POST -d '{"value":"255.255.255.255"}' "$BASE/api/v1/entries")"
check "18. 0.0.0.0" "400" "$(api -X POST -d '{"value":"0.0.0.0"}' "$BASE/api/v1/entries")"
echo ""
echo "=== Edge cases: $PASS/$((PASS+FAIL)) ==="
+57
View File
@@ -0,0 +1,57 @@
#!/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)) ==="