mirror of
https://git.sr.ht/~tsileo/microblog.pub
synced 2024-12-22 05:04:27 +00:00
remote follow: use HTML redirect to work around CSP issue
In Chrome, I get the following when trying to use the remote follow form: Refused to send form data to 'https://example.com/remote_follow' because it violates the following Content Security Policy directive: "form-action 'self'". It seems some browsers (but notably not Firefox) apply the form-action policy to the redirect target in addition to the initial form submission endpoint. See: https://github.com/w3c/webappsec-csp/issues/8 In that thread, this workaround is suggested.
This commit is contained in:
parent
793a939046
commit
9db7bdf0fb
1 changed files with 23 additions and 3 deletions
26
app/main.py
26
app/main.py
|
@ -1,4 +1,5 @@
|
|||
import base64
|
||||
import html
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
@ -38,6 +39,7 @@ from starlette.background import BackgroundTask
|
|||
from starlette.datastructures import Headers
|
||||
from starlette.datastructures import MutableHeaders
|
||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
from starlette.responses import HTMLResponse
|
||||
from starlette.responses import JSONResponse
|
||||
from starlette.types import Message
|
||||
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore
|
||||
|
@ -254,6 +256,25 @@ class ActivityPubResponse(JSONResponse):
|
|||
media_type = "application/activity+json"
|
||||
|
||||
|
||||
class HTMLRedirectResponse(HTMLResponse):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
url: str,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
content=f'<a href="{html.escape(url)}">Continue to remote resource</a>',
|
||||
headers={"Refresh": "0;url=" + url},
|
||||
)
|
||||
|
||||
|
||||
@app.get(config.NavBarItems.NOTES_PATH)
|
||||
async def index(
|
||||
request: Request,
|
||||
|
@ -961,7 +982,7 @@ async def post_remote_follow(
|
|||
request: Request,
|
||||
csrf_check: None = Depends(verify_csrf_token),
|
||||
profile: str = Form(),
|
||||
) -> RedirectResponse:
|
||||
) -> HTMLRedirectResponse:
|
||||
if not profile.startswith("@"):
|
||||
profile = f"@{profile}"
|
||||
|
||||
|
@ -970,9 +991,8 @@ async def post_remote_follow(
|
|||
# TODO(ts): error message to user
|
||||
raise HTTPException(status_code=404)
|
||||
|
||||
return RedirectResponse(
|
||||
return HTMLRedirectResponse(
|
||||
remote_follow_template.format(uri=ID),
|
||||
status_code=302,
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue