#!/usr/bin/env python3
"""
Victim component for GHSA-hg6j-4rv6-33pg / CVE-2026-47265.

Runs aiohttp 3.13.5 (vulnerable). Exposes a control endpoint that the
exploiter triggers. When triggered, this victim CLIENT issues an outbound
request to the first-hop origin with a per-request `cookies={...}` kwarg
whose value is a fresh secret read from disk (planted on boot, NOT by the
exploit). The first-hop 302-redirects cross-origin to the collector; on a
vulnerable aiohttp the per-request cookie is re-attached to the cross-origin
request and leaks to the collector.

The exploiter never sees or supplies the secret. It only causes the victim
to act.
"""
import os
import aiohttp
from aiohttp import web

SECRET_PATH = os.environ["SECRET_PATH"]
FIRST_HOP_URL = os.environ["FIRST_HOP_URL"]
COOKIE_NAME = os.environ.get("COOKIE_NAME", "session")


def read_secret() -> str:
    with open(SECRET_PATH, "r") as f:
        return f.read().strip()


async def trigger(request: web.Request) -> web.Response:
    """
    Exploiter-facing control endpoint. Causes the victim aiohttp client to
    perform its normal business request to the first-hop origin, attaching the
    confidential per-request cookie scoped to that origin. The exploiter does
    NOT pass the cookie value here; the victim reads it from its own protected
    store.
    """
    secret = read_secret()
    # New client session per trigger; the per-request cookies kwarg is the
    # affected code path (session-jar cookies are domain-filtered and safe).
    async with aiohttp.ClientSession() as session:
        async with session.get(
            FIRST_HOP_URL,
            cookies={COOKIE_NAME: secret},
        ) as resp:
            body = await resp.text()
    return web.Response(
        text=(
            "victim issued first-hop request with a per-request cookie; "
            "final response from chain: %r\n" % body[:200]
        )
    )


async def health(request: web.Request) -> web.Response:
    return web.Response(text="ok")


def main() -> None:
    app = web.Application()
    app.router.add_get("/trigger", trigger)
    app.router.add_get("/health", health)
    web.run_app(app, host="0.0.0.0", port=9000)


if __name__ == "__main__":
    main()
