replace check_csrf with require_csrf
Closed this issue · 7 comments
The check_csrf
view predicate as it currently stands is not considered useful because it behaves as a predicate. Thus if the CSRF check fails the normal scenario is that a PredicateMismatch
is raised and results in a 404.
In 1.7 with the introduction of view derivations in #2021 we can add a new require_csrf
derivation that properly raises BadCSRFToken
which can be caught and handled in an exception view. The check_csrf
can be deprecated at this point and potentially removed in the future.
👍
Should require_csrf=
with True
/ False
be the only option? The other issue I can think of is wanting to use the deriver on a view that accepts both get and post, at which point we may want to only require csrf on non-get/head requests (post, put, patch, delete, etc). It seems like it might be a little tough to generalize but I think what I said would work. Maybe this could be overridden by require_csrf='always'
instead of True
or we could just define a few strings instead of true/false. Anyone have some thoughts on this?
Could we allow require_csrf
to be a callable that inspects that request and returns True/False? Might be nice to be able to dynamically enable/disable CSRF checks
well... here's what I didn't mention yet that will influence my answer here: Because of issues like this, the view deriver will probably not be added to your app by default but rather just another thing people can use if they want, similar to the default session factories etc. For example:
config.add_view_deriver(`require_csrf`, `pyramid.session.require_csrf_view`)
If you want something that can do totally custom logic at the point of view declaration then you probably just want decorator=require_csrf
. Passing a callable is better served by the existing decorator
deriver. This PR is about a more declarative approach where you define the policy globally and then you can pass options to it per-view. That's the goal, I'm not saying we'll get there but I don't want to add an API with knobs on it if I don't have to. The idea is that you can already just swap out the require_csrf
view deriver we're talking about here for a different one that may do a better job with your callable.
I think that the CSRF view derivation that we ship with core should come with seat-belts enabled. If you load it, CSRF checking is mandatory for all POST
.
PUT
/DELETE
are not required because they can't be used cross site without OPTIONS. Anyone that needs more flexibility should adapt the code from core and modify it as necessary and load it as a view derivation.
I am a -1 on knobs.
PUT/DELETE are not required because they can't be used cross site without OPTIONS.
Good point about PUT/DELETE that I hadn't considered. It's easy to forget the exact attack vectors that CSRF is protecting against.
If we require_csrf
with True
/False
it will behave mostly like the existing predicate. If we default to False
it will be exactly like the predicate right now, and we could leave it enabled by default and a programmer would have to opt-in per view.