Open bmpenuelas opened 6 years ago
Merging #434 into master will decrease coverage by
0.53%
. The diff coverage is33.33%
.
@@ Coverage Diff @@
## master #434 +/- ##
==========================================
- Coverage 90.67% 90.13% -0.54%
==========================================
Files 14 12 -2
Lines 847 821 -26
Branches 29 30 +1
==========================================
- Hits 768 740 -28
- Misses 66 67 +1
- Partials 13 14 +1
Flag | Coverage Δ | |
---|---|---|
#codecov | 90.13% <33.33%> (-0.54%) |
:arrow_down: |
#dj110 | 86.84% <33.33%> (-0.64%) |
:arrow_down: |
#dj111 | 86.84% <33.33%> (-0.64%) |
:arrow_down: |
#dj18 | 89.28% <33.33%> (-0.57%) |
:arrow_down: |
#dj19 | 89.28% <33.33%> (-0.57%) |
:arrow_down: |
#drf31 | 89.28% <33.33%> (-0.57%) |
:arrow_down: |
#drf32 | 89.28% <33.33%> (-0.57%) |
:arrow_down: |
#drf33 | 89.28% <33.33%> (-0.57%) |
:arrow_down: |
#drf34 | 90.13% <33.33%> (-0.54%) |
:arrow_down: |
#drf35 | 89.76% <33.33%> (-0.56%) |
:arrow_down: |
#drf36 | 89.76% <33.33%> (-0.56%) |
:arrow_down: |
#py27 | 90.13% <33.33%> (-0.54%) |
:arrow_down: |
#py33 | 88.91% <33.33%> (-0.58%) |
:arrow_down: |
#py34 | 89.76% <33.33%> (+0.27%) |
:arrow_up: |
#py35 | 86.84% <33.33%> (?) |
|
#py36 | 86.84% <33.33%> (?) |
Impacted Files | Coverage Δ | |
---|---|---|
rest_framework_jwt/settings.py | 100% <ø> (ø) |
:arrow_up: |
rest_framework_jwt/views.py | 88.37% <33.33%> (-4.13%) |
:arrow_down: |
rest_framework_jwt/utils.py | ||
rest_framework_jwt/models.py |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update 0a0bd40...c64a947. Read the comment docs.
I think this changes are not enough for CSRF protection when JWT_AUTH_COOKIE option is enabled. Your patch adds csrf cookie, but looks like it's value will be never checked, because django-rest-framework explicitly wraps every view in csrf_exempt().
https://github.com/encode/django-rest-framework/blob/master/rest_framework/views.py#L134
I believe that BaseJSONWebTokenAuthentication authentication class should enforce csrf validation when needed. Like in rest_framework.authentication.SessionAuthentication, which explicitly call CSRFCheck?
Hi @yurikulaz, actually, with this patch the csrf value will be checked for every method that you explicitly declare you want checked.
For example, you can try with @method_decorator(csrf_protect)
Nevertheless, enforcing the csrf check by default and declaring exemptions explicitly is the safer way to code. I'll definitely look into adding that too.
@bmpenuelas Thanks for writing this patch! Is this PR a comprehensive fix (with using the csrf decorator)? Is there any reason why I shouldn't make a custom .whl
for this before merge? Is there a timeline for merge?
Yes @jheld , using the csrf decorator, this fix alone can provide the desired protection.
Does this protect against login csrf?
@paul110590 CSRF implies that the attack is executed from another domain, if you want to know whether if the user login is protected then yes, the malicious domain cannot read the CSRF token which belongs to your domain, and thus, the request will fail.
Hi @bmpenuelas , what I mean is the CSRF token is not set until the JWT is issued, i.e. after the user has logged in. Therefore an attacker could log in via CSRF and the user would think they were logged in to their own account. The user would then unwittingly be performing actions on the attacker's account. Or is there some protection against this that I am missing?
Protection is generally geared toward avoiding forging user requests. That protection is provided by the Anti-CSRF token and the JWT token working together.
In the particular case you mention, at no time is the user session compromised. It's not a threat like user-impersonating CSRF, but it's true it can have privacy implications. I don't want to go off-topic here since this isn't related to the pull-request itself, but CSRFToken can protect your application from this situation too. For example, you can issue an Anti-CSRF token for the login process, and store it as both: a hidden form value, and a cookie. To validate the login request, both values must match, and since an attacker can't read them both, the login will fail.
It's a different type of csrf to the more common session riding, but it's still a security flaw we need to protect against.
This is where I think it has relevancy to the pull request: To protect against login-csrf we need to decorate our login view with csrf_protect. We then need to create a view that will set the csrftoken cookie, so that we can fetch it prior to login and our login request is not blocked. This being the case, we no longer need to set the csrftoken cookie when we issue the JWT, because it is already set.
Basically, if we follow the approach of protecting ourselves from login-csrf we will also automatically be protecting ourselves from 'normal' csrf (provided we guard all unsafe views with csrf_protect). Whereas if we follow the approach of protecting from 'normal' csrf, we are still leaving ourselves open to login-csrf.
Yes, this PR already does that. CSRF tokens are issued for every request, not only after login, so you can use them for login, or to protect other requests, the same principles apply.
The problem before this PR was that when you used the JWT token for authentication, the CSRF token was ignored.
Any ideas when this PR is going to be merged into the package? Does it need work, can I help in any way getting this out the door?
@pc-trent offer sacrifices to @gcollazo and @jpadilla . c.f. https://github.com/GetBlimp/django-rest-framework-jwt/issues/449
@pc-trent offer sacrifices to @gcollazo and @jpadilla . c.f. #449
I'll take that as a "this project is dead"
We should hope not. Maybe we can ask for maintainer privileges? Including PyPI. We've been waiting for this fix for a year.
To prevent Cross-Site Request Forgery when using JWT_AUTH_COOKIE, the
csrftoken
cookie will also be set when issuing the JWT authentication token.