Files
iqon/scripts/iqon-phase1-verify.sh
2026-05-20 18:17:20 +03:00

111 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPEC: wp-snippets/README.md#verification
# Compliance date: 2026-05-20
# Launch type: manual post-deployment verification
# Registry: iqon Phase 1 hardening verification
set -u
BASE_URL="${1:-https://iqon.com}"
FAILED=0
note() {
printf '\n[%s] %s\n' "$1" "$2"
}
fail() {
FAILED=1
printf '[FAIL] %s\n' "$1"
}
pass() {
printf '[PASS] %s\n' "$1"
}
fetch_headers() {
curl -sS -I -L "$BASE_URL/"
}
fetch_home() {
curl -sS -L "$BASE_URL/"
}
note CHECK "Security headers"
if ! HEADERS="$(fetch_headers)"; then
HEADERS=""
fail 'could not fetch homepage headers'
fi
printf '%s\n' "$HEADERS" | rg -qi '^x-content-type-options:\s*nosniff' \
&& pass 'X-Content-Type-Options present' \
|| fail 'X-Content-Type-Options missing'
printf '%s\n' "$HEADERS" | rg -qi '^x-frame-options:\s*SAMEORIGIN' \
&& pass 'X-Frame-Options present' \
|| fail 'X-Frame-Options missing'
printf '%s\n' "$HEADERS" | rg -qi '^referrer-policy:' \
&& pass 'Referrer-Policy present' \
|| fail 'Referrer-Policy missing'
printf '%s\n' "$HEADERS" | rg -qi '^permissions-policy:' \
&& pass 'Permissions-Policy present' \
|| fail 'Permissions-Policy missing'
printf '%s\n' "$HEADERS" | rg -qi '^content-security-policy:' \
&& pass 'Content-Security-Policy present' \
|| fail 'Content-Security-Policy missing'
note CHECK "Homepage HTML"
if HOME="$(fetch_home)"; then
printf '%s\n' "$HOME" | rg -q 'name=["'\'']viewport["'\'']' \
&& pass 'viewport present' \
|| fail 'viewport missing'
printf '%s\n' "$HOME" | rg -q 'class=["'\''][^"'\'']*(iqon-skip-link|skip-link)' \
&& pass 'skip link present' \
|| fail 'skip link missing'
printf '%s\n' "$HOME" | rg -q 'http://www\.iqon\.com|http://iqon\.com|http://maps\.google\.com|http://maps\.googleapis\.com' \
&& fail 'known HTTP URLs still present' \
|| pass 'known HTTP URLs absent'
printf '%s\n' "$HOME" | rg -q 'property=["'\'']og:site_name["'\''][^>]*content=["'\'']- IQON["'\'']' \
&& fail 'og:site_name still has - IQON' \
|| pass 'og:site_name no longer has - IQON'
else
fail 'could not fetch homepage HTML'
fi
note CHECK "REST users endpoint"
if USERS_BODY="$(curl -sS -L "$BASE_URL/wp-json/wp/v2/users")"; then
printf '%s\n' "$USERS_BODY" | rg -q '"slug"\s*:\s*"(admin|iqnadm01)"' \
&& fail 'public REST users still exposed' \
|| pass 'public REST users not exposed'
else
fail 'could not fetch REST users endpoint'
fi
note CHECK "Install documents"
README_STATUS="$(curl -sS -o /dev/null -w '%{http_code}' -L "$BASE_URL/readme.html")"
case "$README_STATUS" in
403|404) pass "readme.html blocked with $README_STATUS" ;;
*) fail "readme.html returned $README_STATUS" ;;
esac
note CHECK "XML-RPC HEAD smoke"
XMLRPC_STATUS="$(curl -sS -o /dev/null -w '%{http_code}' -I --http1.1 "$BASE_URL/xmlrpc.php")"
XMLRPC_CURL_STATUS=$?
case "$XMLRPC_STATUS" in
403|404|405) pass "xmlrpc.php not plainly usable via HEAD: $XMLRPC_STATUS" ;;
000)
if [ "$XMLRPC_CURL_STATUS" -eq 52 ]; then
pass "xmlrpc.php returned empty reply via HEAD: $XMLRPC_STATUS"
else
fail "xmlrpc.php check failed with curl status $XMLRPC_CURL_STATUS"
fi
;;
*) fail "xmlrpc.php returned $XMLRPC_STATUS; run safe POST check" ;;
esac
printf '\n'
if [ "$FAILED" -eq 0 ]; then
printf '[OK] iqon Phase 1 verification passed for %s\n' "$BASE_URL"
else
printf '[FAIL] iqon Phase 1 verification failed for %s\n' "$BASE_URL"
fi
exit "$FAILED"