html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app https://github.com/simonw/datasette/issues/835#issuecomment-646308467,https://api.github.com/repos/simonw/datasette/issues/835,646308467,MDEyOklzc3VlQ29tbWVudDY0NjMwODQ2Nw==,9599,2020-06-18T21:12:50Z,2020-06-18T21:12:50Z,OWNER,"Problem there is Login CSRF attacks: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#login-csrf - I still want to perform CSRF checks on login forms, even though the user may not yet have any cookies. Maybe I can turn off CSRF checks for cookie-free requests but allow login forms to specifically opt back in to CSRF protection?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646307083,https://api.github.com/repos/simonw/datasette/issues/835,646307083,MDEyOklzc3VlQ29tbWVudDY0NjMwNzA4Mw==,9599,2020-06-18T21:09:35Z,2020-06-18T21:09:35Z,OWNER,So maybe one really easy fix here is to disable CSRF checks entirely for any request that doesn't have any cookies? Also suggested here: https://twitter.com/mrkurt/status/1273682965168603137,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646288146,https://api.github.com/repos/simonw/datasette/issues/835,646288146,MDEyOklzc3VlQ29tbWVudDY0NjI4ODE0Ng==,9599,2020-06-18T20:26:22Z,2020-06-18T20:26:31Z,OWNER,"Useful tip from Carlton Gibson: https://twitter.com/carltongibson/status/1273680590672453632 > DRF makes ALL views CSRF exempt and then enforces CSRF if you're using Session auth only. > > View: https://github.com/encode/django-rest-framework/blob/e18e40d6ae42457f60ca9c68054ad40d15ba8433/rest_framework/views.py#L144 > Auth: https://github.com/encode/django-rest-framework/blob/e18e40d6ae42457f60ca9c68054ad40d15ba8433/rest_framework/authentication.py#L130","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646217766,https://api.github.com/repos/simonw/datasette/issues/835,646217766,MDEyOklzc3VlQ29tbWVudDY0NjIxNzc2Ng==,9599,2020-06-18T17:55:54Z,2020-06-18T17:56:04Z,OWNER,Idea: a mechanism where the `asgi_csrf()` can take an optional `should_protect()` callback function which gets called with the `scope` and decides if the current request should be protected or not. It can then look at headers and paths and suchlike and make its own decisions. Datasette could then provide a `should_protect()` callback which can interact with plugins.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646216934,https://api.github.com/repos/simonw/datasette/issues/835,646216934,MDEyOklzc3VlQ29tbWVudDY0NjIxNjkzNA==,9599,2020-06-18T17:54:14Z,2020-06-18T17:54:14Z,OWNER,"> if you did Origin based CSRF checks, then could the absence of an Origin header be used? https://twitter.com/cnorthwood/status/1273674392757829632","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646214158,https://api.github.com/repos/simonw/datasette/issues/835,646214158,MDEyOklzc3VlQ29tbWVudDY0NjIxNDE1OA==,9599,2020-06-18T17:48:45Z,2020-06-18T17:48:45Z,OWNER,"I wonder if it's safe to generically say ""Don't do CSRF protection on any request that includes a `Authorization: Bearer...` header - because it's not possible for a regular browser to send that header since the format is different from the header used in browser-based HTTP basic auth?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646209520,https://api.github.com/repos/simonw/datasette/issues/835,646209520,MDEyOklzc3VlQ29tbWVudDY0NjIwOTUyMA==,9599,2020-06-18T17:39:30Z,2020-06-18T17:40:53Z,OWNER,"`datasette-auth-tokens` could switch to using `asgi_wrapper` instead of `actor_from_request` - then it could add a `scope[""skip_csrf""] = True` scope property to indicate that CSRF should not be protected. Since `asgi_wrapper` wraps the CSRF protection middleware changes made to the `scope` by an `asgi_wrapper` will be visible to the CSRF middleware: https://github.com/simonw/datasette/blob/d2aef9f7ef30fa20b1450cd181cf803f44fb4e21/datasette/app.py#L877-L888","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646204308,https://api.github.com/repos/simonw/datasette/issues/835,646204308,MDEyOklzc3VlQ29tbWVudDY0NjIwNDMwOA==,9599,2020-06-18T17:32:41Z,2020-06-18T17:32:41Z,OWNER,The only way I can think of for a view to opt-out of CSRF protection is for them to be able to reconfigure the `asgi-csrf` middleware to skip specific URL patterns.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646175055,https://api.github.com/repos/simonw/datasette/issues/835,646175055,MDEyOklzc3VlQ29tbWVudDY0NjE3NTA1NQ==,9599,2020-06-18T17:00:45Z,2020-06-18T17:00:45Z,OWNER,Here's the Rails pattern for this: https://gist.github.com/maxivak/a25957942b6c21a41acd,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646172200,https://api.github.com/repos/simonw/datasette/issues/835,646172200,MDEyOklzc3VlQ29tbWVudDY0NjE3MjIwMA==,9599,2020-06-18T16:57:45Z,2020-06-18T16:57:45Z,OWNER,"I think there are a couple of steps to this one. The nature of CSRF is that it's about hijacking existing authentication credentials. If your Datasette site runs without any authentication plugins at all CSRF protection isn't actually useful. Some POST endpoints should be able to opt-out of CSRF protection entirely. A writable canned query that accepts anonymous poll submissions for example might determine that CSRF is not needed. If a plugin adds `Authorization: Bearer xxx` token support that plugin should also be able to specify that CSRF protection can be skipped. https://github.com/simonw/datasette-auth-tokens could do this. This means I need two new mechanisms: - A way for wrapped views to indicate ""actually don't CSRF protect me"". I'm not sure how feasible this is without a major redesign, since the decision to return a 403 forbidden status is made before the wrapped function has even been called. - A way for authentication plugins like `datasette-auth-tokens` to say ""CSRF protection is not needed for this request"". This is a bit tricky too, since right now the `actor_from_request` hook doesn't have a channel for information other than returning the actor dictionary.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686, https://github.com/simonw/datasette/issues/835#issuecomment-646151706,https://api.github.com/repos/simonw/datasette/issues/835,646151706,MDEyOklzc3VlQ29tbWVudDY0NjE1MTcwNg==,9599,2020-06-18T16:36:23Z,2020-06-18T16:36:23Z,OWNER,Tweeted about this here: https://twitter.com/simonw/status/1273655053170077701,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",637363686,