From db6016394bd478c77dce20e8d2947f7206128007 Mon Sep 17 00:00:00 2001 From: Thomas Sileo Date: Fri, 16 Dec 2022 09:22:40 +0100 Subject: [PATCH] Fix CSP IndieAuth redirection issue --- app/indieauth.py | 9 ++++----- app/redirect.py | 28 ++++++++++++++++++++++++++++ app/templates/redirect.html | 15 +++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 app/redirect.py create mode 100644 app/templates/redirect.html diff --git a/app/indieauth.py b/app/indieauth.py index f96e522..bbcc096 100644 --- a/app/indieauth.py +++ b/app/indieauth.py @@ -10,7 +10,6 @@ from fastapi import Form from fastapi import HTTPException from fastapi import Request from fastapi.responses import JSONResponse -from fastapi.responses import RedirectResponse from loguru import logger from sqlalchemy import select @@ -21,6 +20,7 @@ from app.admin import user_session_or_redirect from app.config import verify_csrf_token from app.database import AsyncSession from app.database import get_db_session +from app.redirect import redirect from app.utils import indieauth from app.utils.datetime import now @@ -80,7 +80,7 @@ async def indieauth_flow( db_session: AsyncSession = Depends(get_db_session), csrf_check: None = Depends(verify_csrf_token), _: None = Depends(user_session_or_redirect), -) -> RedirectResponse: +) -> templates.TemplateResponse: form_data = await request.form() logger.info(f"{form_data=}") @@ -114,9 +114,8 @@ async def indieauth_flow( db_session.add(auth_request) await db_session.commit() - return RedirectResponse( - redirect_uri + f"?code={code}&state={state}&iss={iss}", - status_code=302, + return await redirect( + request, db_session, redirect_uri + f"?code={code}&state={state}&iss={iss}" ) diff --git a/app/redirect.py b/app/redirect.py new file mode 100644 index 0000000..137e80b --- /dev/null +++ b/app/redirect.py @@ -0,0 +1,28 @@ +from fastapi import Request + +from app import templates +from app.database import AsyncSession + + +async def redirect( + request: Request, + db_session: AsyncSession, + url: str, +) -> templates.TemplateResponse: + """ + Similar to RedirectResponse, but uses a 200 response with HTML. + + Needed for remote redirects on form submission endpoints, + since our CSP policy disallows remote form submission. + https://github.com/w3c/webappsec-csp/issues/8#issuecomment-810108984 + """ + return await templates.render_template( + db_session, + request, + "redirect.html", + { + "request": request, + "url": url, + }, + headers={"Refresh": "0;url=" + url}, + ) diff --git a/app/templates/redirect.html b/app/templates/redirect.html new file mode 100644 index 0000000..f8b0601 --- /dev/null +++ b/app/templates/redirect.html @@ -0,0 +1,15 @@ +{%- import "utils.html" as utils with context -%} +{% extends "layout.html" %} + +{% block head %} +{{ local_actor.display_name }}'s microblog - Redirect +{% endblock %} + +{% block content %} +{% include "header.html" %} + +
+

You are being redirected to: {{ url }}

+
+ +{% endblock %}