recent updates
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env bash
|
||||
# verify-protection.sh — confirm a deployed Arising Media site is not leaking
|
||||
# build artifacts, server config, or dotfiles to the public web.
|
||||
#
|
||||
# Usage:
|
||||
# ./verify-protection.sh <base-url>
|
||||
# ./verify-protection.sh http://localhost:8010
|
||||
# ./verify-protection.sh https://cobhamtech.com
|
||||
#
|
||||
# Exit 0 if every check passes, 1 otherwise. Designed to be run after every
|
||||
# deploy and in CI.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE="${1:-}"
|
||||
if [[ -z "$BASE" ]]; then
|
||||
echo "usage: $0 <base-url>" >&2
|
||||
exit 2
|
||||
fi
|
||||
BASE="${BASE%/}"
|
||||
|
||||
# Required paths — site must serve these; missing = audit FAIL.
|
||||
REQUIRED=(
|
||||
"/"
|
||||
)
|
||||
|
||||
# Public paths — should be reachable; missing = WARN (content gap, not a leak).
|
||||
PUBLIC=(
|
||||
"/robots.txt"
|
||||
"/sitemap.xml"
|
||||
)
|
||||
|
||||
# Sensitive paths — must NOT return 200. 404 or 403 is acceptable.
|
||||
# This list mirrors the deny patterns in SOP 08 nginx.conf.
|
||||
SENSITIVE=(
|
||||
"/Dockerfile"
|
||||
"/dockerfile"
|
||||
"/docker-compose.yml"
|
||||
"/nginx.conf"
|
||||
"/.dockerignore"
|
||||
"/.gitignore"
|
||||
"/.git/config"
|
||||
"/.git/HEAD"
|
||||
"/.env"
|
||||
"/.env.example"
|
||||
"/api/.env"
|
||||
"/.planning/"
|
||||
"/.planning/build_locations.py"
|
||||
"/.planning/build_services.py"
|
||||
"/.planning/regen_images.py"
|
||||
"/.planning/playwright_audit.py"
|
||||
"/__pycache__/"
|
||||
"/build_locations.py"
|
||||
"/build_services.py"
|
||||
"/regen_images.py"
|
||||
"/playwright_audit.py"
|
||||
"/server.py"
|
||||
"/main.py"
|
||||
"/README.md"
|
||||
"/package.json"
|
||||
"/composer.json"
|
||||
)
|
||||
|
||||
fail=0
|
||||
|
||||
warn=0
|
||||
|
||||
probe() {
|
||||
local path="$1"
|
||||
local expect="$2" # public | required | sensitive
|
||||
local code
|
||||
code=$(curl -k -s -o /dev/null -w '%{http_code}' --max-time 5 "${BASE}${path}" || echo "000")
|
||||
case "$expect" in
|
||||
required)
|
||||
if [[ "$code" =~ ^(200|301|302|304)$ ]]; then
|
||||
printf ' OK %-3s %s\n' "$code" "$path"
|
||||
else
|
||||
printf ' FAIL %-3s %s (required public path unreachable)\n' "$code" "$path"
|
||||
fail=1
|
||||
fi
|
||||
;;
|
||||
public)
|
||||
if [[ "$code" =~ ^(200|301|302|304)$ ]]; then
|
||||
printf ' OK %-3s %s\n' "$code" "$path"
|
||||
else
|
||||
printf ' WARN %-3s %s (public path unreachable — content gap, not a leak)\n' "$code" "$path"
|
||||
warn=1
|
||||
fi
|
||||
;;
|
||||
sensitive)
|
||||
if [[ "$code" == "200" ]]; then
|
||||
printf ' LEAK %-3s %s (must not return 200)\n' "$code" "$path"
|
||||
fail=1
|
||||
else
|
||||
printf ' OK %-3s %s\n' "$code" "$path"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "Verifying ${BASE}"
|
||||
echo
|
||||
echo "Required paths (site must serve these):"
|
||||
for p in "${REQUIRED[@]}"; do probe "$p" required; done
|
||||
echo
|
||||
echo "Public paths (should be reachable):"
|
||||
for p in "${PUBLIC[@]}"; do probe "$p" public; done
|
||||
echo
|
||||
echo "Sensitive paths (must not be reachable):"
|
||||
for p in "${SENSITIVE[@]}"; do probe "$p" sensitive; done
|
||||
echo
|
||||
|
||||
if [[ $fail -ne 0 ]]; then
|
||||
echo "FAIL — exposure or required-path failure at ${BASE}" >&2
|
||||
exit 1
|
||||
elif [[ $warn -ne 0 ]]; then
|
||||
echo "PASS (with warnings) — no exposure at ${BASE}, but missing public content"
|
||||
exit 0
|
||||
else
|
||||
echo "PASS — no exposure detected at ${BASE}"
|
||||
exit 0
|
||||
fi
|
||||
Reference in New Issue
Block a user