mirror of
				https://git.sr.ht/~tsileo/microblog.pub
				synced 2025-06-05 21:59:23 +02: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:
		
				
					committed by
					
						 Thomas Sileo
						Thomas Sileo
					
				
			
			
				
	
			
			
			
						parent
						
							793a939046
						
					
				
				
					commit
					9db7bdf0fb
				
			
							
								
								
									
										26
									
								
								app/main.py
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								app/main.py
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | |||||||
| import base64 | import base64 | ||||||
|  | import html | ||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
| import time | import time | ||||||
| @@ -38,6 +39,7 @@ from starlette.background import BackgroundTask | |||||||
| from starlette.datastructures import Headers | from starlette.datastructures import Headers | ||||||
| from starlette.datastructures import MutableHeaders | from starlette.datastructures import MutableHeaders | ||||||
| from starlette.exceptions import HTTPException as StarletteHTTPException | from starlette.exceptions import HTTPException as StarletteHTTPException | ||||||
|  | from starlette.responses import HTMLResponse | ||||||
| from starlette.responses import JSONResponse | from starlette.responses import JSONResponse | ||||||
| from starlette.types import Message | from starlette.types import Message | ||||||
| from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware  # type: ignore | from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware  # type: ignore | ||||||
| @@ -254,6 +256,25 @@ class ActivityPubResponse(JSONResponse): | |||||||
|     media_type = "application/activity+json" |     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) | @app.get(config.NavBarItems.NOTES_PATH) | ||||||
| async def index( | async def index( | ||||||
|     request: Request, |     request: Request, | ||||||
| @@ -961,7 +982,7 @@ async def post_remote_follow( | |||||||
|     request: Request, |     request: Request, | ||||||
|     csrf_check: None = Depends(verify_csrf_token), |     csrf_check: None = Depends(verify_csrf_token), | ||||||
|     profile: str = Form(), |     profile: str = Form(), | ||||||
| ) -> RedirectResponse: | ) -> HTMLRedirectResponse: | ||||||
|     if not profile.startswith("@"): |     if not profile.startswith("@"): | ||||||
|         profile = f"@{profile}" |         profile = f"@{profile}" | ||||||
|  |  | ||||||
| @@ -970,9 +991,8 @@ async def post_remote_follow( | |||||||
|         # TODO(ts): error message to user |         # TODO(ts): error message to user | ||||||
|         raise HTTPException(status_code=404) |         raise HTTPException(status_code=404) | ||||||
|  |  | ||||||
|     return RedirectResponse( |     return HTMLRedirectResponse( | ||||||
|         remote_follow_template.format(uri=ID), |         remote_follow_template.format(uri=ID), | ||||||
|         status_code=302, |  | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user