#!/bin/bash # # NODE1 Security Regression Test # Version: 1.0 # Last Updated: 2026-01-26 # # Run after each deploy to verify security posture # # Usage: ./security-regression-test.sh [--remote] # # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # Config HOST="${TEST_HOST:-https://gateway.daarion.city}" HEALTH_TOKEN="${HEALTH_TOKEN:-dg-health-2026-secret-change-me}" passed=0 failed=0 warnings=0 # Test helper test_check() { local name="$1" local result="$2" local expected="$3" if [ "$result" = "$expected" ]; then echo -e "${GREEN}✅ PASS${NC}: $name" ((passed++)) else echo -e "${RED}❌ FAIL${NC}: $name (got: $result, expected: $expected)" ((failed++)) fi } test_contains() { local name="$1" local haystack="$2" local needle="$3" if echo "$haystack" | grep -qi "$needle"; then echo -e "${GREEN}✅ PASS${NC}: $name" ((passed++)) else echo -e "${RED}❌ FAIL${NC}: $name (missing: $needle)" ((failed++)) fi } echo "========================================" echo " NODE1 Security Regression Test" echo " $(date '+%Y-%m-%d %H:%M:%S')" echo " Target: $HOST" echo "========================================" echo "" # === 1. TLS/HSTS === echo "=== 1. TLS & Security Headers ===" headers=$(curl -sS -k -I "$HOST/ping" 2>&1) test_contains "HSTS header present" "$headers" "strict-transport-security" test_contains "X-Frame-Options present" "$headers" "x-frame-options" test_contains "X-Content-Type-Options present" "$headers" "x-content-type-options" test_contains "X-XSS-Protection present" "$headers" "x-xss-protection" test_contains "Content-Security-Policy present" "$headers" "content-security-policy" echo "" # === 2. HTTP→HTTPS Redirect === echo "=== 2. HTTP→HTTPS Redirect ===" http_host="${HOST/https:/http:}" redirect_code=$(curl -sS -o /dev/null -w "%{http_code}" "$http_host/ping" 2>/dev/null || echo "000") test_check "HTTP redirects to HTTPS" "$redirect_code" "301" echo "" # === 3. /health Protection === echo "=== 3. /health Endpoint Protection ===" # Without token (should be 401 or blocked) health_no_token=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/health" 2>/dev/null || echo "000") if [ "$health_no_token" = "401" ] || [ "$health_no_token" = "403" ]; then echo -e "${GREEN}✅ PASS${NC}: /health without token blocked ($health_no_token)" ((passed++)) else echo -e "${RED}❌ FAIL${NC}: /health without token NOT blocked ($health_no_token)" ((failed++)) fi # /ping should work without auth ping_code=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/ping" 2>/dev/null || echo "000") test_check "/ping accessible without auth" "$ping_code" "200" echo "" # === 4. API Auth Gate === echo "=== 4. API Auth Gate (/v1/*) ===" # Without key (should be 401) v1_no_key=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/v1/test" 2>/dev/null || echo "000") test_check "/v1/* without API key returns 401" "$v1_no_key" "401" # With invalid key format v1_bad_key=$(curl -sS -k -o /dev/null -w "%{http_code}" -H "Authorization: Bearer invalid" "$HOST/v1/test" 2>/dev/null || echo "000") test_check "/v1/* with invalid key format returns 401" "$v1_bad_key" "401" echo "" # === 5. WAF Rules === echo "=== 5. WAF Rules ===" # .env should be blocked (444 = connection closed, shows as 000 in curl) env_code=$(curl -sS -k -o /dev/null -w "%{http_code}" --max-time 5 "$HOST/.env" 2>&1 | grep -oE '[0-9]{3}$' | tail -1 || echo "000") # 000 means connection was closed (444), which is blocked if [[ "$env_code" =~ ^0+$ ]] || [ "$env_code" = "444" ] || [ "$env_code" = "403" ]; then echo -e "${GREEN}✅ PASS${NC}: /.env blocked (connection closed)" ((passed++)) || true else echo -e "${RED}❌ FAIL${NC}: /.env NOT blocked ($env_code)" ((failed++)) || true fi # .git should be blocked git_code=$(curl -sS -k -o /dev/null -w "%{http_code}" --max-time 5 "$HOST/.git/config" 2>&1 | grep -oE '[0-9]{3}$' | tail -1 || echo "000") if [[ "$git_code" =~ ^0+$ ]] || [ "$git_code" = "444" ] || [ "$git_code" = "403" ]; then echo -e "${GREEN}✅ PASS${NC}: /.git blocked (connection closed)" ((passed++)) || true else echo -e "${RED}❌ FAIL${NC}: /.git NOT blocked ($git_code)" ((failed++)) || true fi # SQL injection attempt sql_code=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/?q=select+*+from+users" 2>/dev/null || echo "000") test_check "SQL injection blocked" "$sql_code" "403" # wp-admin blocked wp_code=$(curl -sS -k -o /dev/null -w "%{http_code}" --max-time 5 "$HOST/wp-admin/" 2>&1 | grep -oE '[0-9]{3}$' | tail -1 || echo "000") if [[ "$wp_code" =~ ^0+$ ]] || [ "$wp_code" = "444" ] || [ "$wp_code" = "403" ]; then echo -e "${GREEN}✅ PASS${NC}: /wp-admin blocked (connection closed)" ((passed++)) || true else echo -e "${RED}❌ FAIL${NC}: /wp-admin NOT blocked ($wp_code)" ((failed++)) || true fi echo "" # === 6. Rate Limiting === echo "=== 6. Rate Limiting ===" echo -n "Sending 30 rapid requests to /ping... " got_429=false for i in $(seq 1 30); do code=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/ping" 2>/dev/null || echo "000") if [ "$code" = "429" ]; then got_429=true break fi done if [ "$got_429" = true ]; then echo -e "${GREEN}✅ PASS${NC}: Rate limit (429) triggered" ((passed++)) else echo -e "${YELLOW}⚠ WARN${NC}: Rate limit (429) not triggered (may need more requests or higher rate)" ((warnings++)) fi echo "" # === 7. Default Route === echo "=== 7. Default Route Security ===" # Unknown endpoint should not expose info unknown_code=$(curl -sS -k -o /dev/null -w "%{http_code}" "$HOST/unknown-endpoint-xyz" 2>/dev/null || echo "000") if [ "$unknown_code" = "404" ] || [ "$unknown_code" = "401" ] || [ "$unknown_code" = "403" ]; then echo -e "${GREEN}✅ PASS${NC}: Unknown endpoint returns safe code ($unknown_code)" ((passed++)) else echo -e "${YELLOW}⚠ WARN${NC}: Unknown endpoint returns $unknown_code" ((warnings++)) fi echo "" # === Summary === echo "========================================" echo " Security Regression Test Summary" echo "========================================" echo "" echo -e " ${GREEN}Passed:${NC} $passed" echo -e " ${RED}Failed:${NC} $failed" echo -e " ${YELLOW}Warnings:${NC} $warnings" echo "" if [ "$failed" -gt 0 ]; then echo -e "${RED}SECURITY REGRESSION DETECTED${NC}" exit 1 elif [ "$warnings" -gt 0 ]; then echo -e "${YELLOW}Tests passed with warnings${NC}" exit 0 else echo -e "${GREEN}All security tests passed${NC}" exit 0 fi