diff --git a/scripts/upgrade_fixtures_box.py b/scripts/upgrade_fixtures_box.py index 1d13e78..c45f9c4 100644 --- a/scripts/upgrade_fixtures_box.py +++ b/scripts/upgrade_fixtures_box.py @@ -1413,12 +1413,16 @@ class Outline: self.tried = f"POST /api/installation.create -> {code}" return None rc, code, out = w.app_curl(sub, "/home", "-D", "-", "-o", "/dev/null", "-H", f"Cookie: {ck}") - csrf = re.search(r"(?im)^set-cookie:\s*csrfToken=([^;\r\n]+)", out or "") + # R-744: Outline 1.10 names the cookie `__Host-csrfToken` on a secure request (server/utils/csrf.ts getCookieName, + # shared/constants.ts CSRF.secureCookieName) and `csrfToken` over plain HTTP — 1.9.1 always said `csrfToken`. + # The double-submit check compares the cookie under the request's own name with the x-csrf-token header. + csrf = re.search(r"(?im)^set-cookie:\s*((?:__Host-)?csrfToken)=([^;\r\n]+)", out or "") if not csrf: - self.tried = "no csrfToken cookie from GET /home" + self.tried = "no csrfToken / __Host-csrfToken cookie from GET /home" return None - cs = csrf.group(1) - rc, code, out = w.app_curl(sub, "/api/apiKeys.create", "-H", f"Cookie: {ck}; csrfToken={cs}", "-H", f"x-csrf-token: {cs}", + cn, cs = csrf.group(1), csrf.group(2) + say(f" outline: CSRF cookie {cn}") + rc, code, out = w.app_curl(sub, "/api/apiKeys.create", "-H", f"Cookie: {ck}; {cn}={cs}", "-H", f"x-csrf-token: {cs}", "-H", "Content-Type: application/json", "-H", f"Origin: {o}", data=json.dumps({"name": "drill"}), method="POST") try: