111 lines
3.9 KiB
Bash
Executable File
111 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
|
|
DB_PATH="${DB_PATH:-fixture/fixture.db}"
|
|
RUN_ID="${RUN_ID:-$(date +%s)}"
|
|
|
|
echo "[security-smoke] checking service readiness"
|
|
curl -fsS -H 'X-WP-User: admin' "$BASE_URL/wp-json/calendar/v1/events" >/dev/null
|
|
|
|
echo "[security-smoke] checking register token non-disclosure"
|
|
register_email="sec-nodisclose-${RUN_ID}@example.test"
|
|
reg_code="$(curl -sS -o /tmp/sec_register.json -w '%{http_code}' -H 'Content-Type: application/json' \
|
|
-d "{\"email\":\"${register_email}\",\"password\":\"strongpass123\"}" \
|
|
"$BASE_URL/wp-json/calendar/v1/users/register")"
|
|
if [ "$reg_code" != "200" ] && [ "$reg_code" != "201" ] && [ "$reg_code" != "409" ]; then
|
|
echo "[security-smoke] FAIL: unexpected register status $reg_code"
|
|
exit 1
|
|
fi
|
|
reg_payload="$(cat /tmp/sec_register.json)"
|
|
if echo "$reg_payload" | grep -q 'verification_token_fixture'; then
|
|
echo "[security-smoke] FAIL: register response leaked verification token"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[security-smoke] checking forgot-password token non-disclosure"
|
|
forgot_payload="$(curl -fsS -H 'Content-Type: application/json' \
|
|
-d '{"email":"adrians@chezstephens.org.uk"}' \
|
|
"$BASE_URL/wp-json/calendar/v1/users/forgot-password")"
|
|
if echo "$forgot_payload" | grep -q 'reset_token_fixture'; then
|
|
echo "[security-smoke] FAIL: forgot-password response leaked reset token"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[security-smoke] checking register rate limiting"
|
|
seen_429=0
|
|
rate_prefix="sec-rate-${RUN_ID}"
|
|
for i in $(seq 1 10); do
|
|
code="$(curl -sS -o /tmp/sec_reg_$i.json -w '%{http_code}' \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{\"email\":\"${rate_prefix}-$i@example.test\",\"password\":\"strongpass123\"}" \
|
|
"$BASE_URL/wp-json/calendar/v1/users/register")"
|
|
if [ "$code" = "429" ]; then
|
|
seen_429=1
|
|
break
|
|
fi
|
|
done
|
|
if [ "$seen_429" -ne 1 ]; then
|
|
echo "[security-smoke] FAIL: expected 429 from register rate limiter"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[security-smoke] checking password hash format in database"
|
|
python3 - "$DB_PATH" <<'PY'
|
|
import sqlite3
|
|
import sys
|
|
|
|
db_path = sys.argv[1]
|
|
conn = sqlite3.connect(db_path)
|
|
cur = conn.cursor()
|
|
rows = cur.execute("SELECT email, password_hash FROM caldav_users").fetchall()
|
|
conn.close()
|
|
if not rows:
|
|
print("[security-smoke] FAIL: no users found")
|
|
raise SystemExit(1)
|
|
for email, pw_hash in rows:
|
|
if not isinstance(pw_hash, str) or not pw_hash.startswith("pbkdf2_sha256$"):
|
|
print(f"[security-smoke] FAIL: non-pbkdf2 hash for {email}: {pw_hash!r}")
|
|
raise SystemExit(1)
|
|
print("[security-smoke] password hash format OK")
|
|
PY
|
|
|
|
echo "[security-smoke] checking strict CalDAV resource filename semantics"
|
|
resource="sec-$(date +%s).ics"
|
|
cat > /tmp/sec_caldav.ics <<'ICS'
|
|
BEGIN:VCALENDAR
|
|
VERSION:2.0
|
|
PRODID:-//Security Smoke//EN
|
|
BEGIN:VEVENT
|
|
UID:sec-smoke-uid@example.test
|
|
SUMMARY:Security Smoke Event
|
|
DTSTART:20260415T100000
|
|
DTEND:20260415T110000
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
ICS
|
|
put_code="$(curl -sS -o /tmp/sec_caldav_put.json -w '%{http_code}' \
|
|
-u adrians@chezstephens.org.uk:brillig1 \
|
|
-X PUT --data-binary @/tmp/sec_caldav.ics \
|
|
"$BASE_URL/caldav/calendars/public/$resource")"
|
|
if [ "$put_code" != "201" ] && [ "$put_code" != "200" ]; then
|
|
echo "[security-smoke] FAIL: expected 200/201 for CalDAV PUT, got $put_code"
|
|
exit 1
|
|
fi
|
|
get_code="$(curl -sS -o /tmp/sec_caldav_get.ics -w '%{http_code}' \
|
|
-u adrians@chezstephens.org.uk:brillig1 \
|
|
"$BASE_URL/caldav/calendars/public/$resource")"
|
|
if [ "$get_code" != "200" ]; then
|
|
echo "[security-smoke] FAIL: expected 200 for CalDAV GET on same resource, got $get_code"
|
|
exit 1
|
|
fi
|
|
missing_code="$(curl -sS -o /tmp/sec_caldav_missing.out -w '%{http_code}' \
|
|
-u adrians@chezstephens.org.uk:brillig1 \
|
|
"$BASE_URL/caldav/calendars/public/999999.ics")"
|
|
if [ "$missing_code" != "404" ]; then
|
|
echo "[security-smoke] FAIL: expected 404 for unknown numeric resource, got $missing_code"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[security-smoke] all checks passed"
|