New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix downloads in Chrome with xsrf token #6686
Conversation
Thanks for making a pull request to JupyterLab! To try out this branch on binder, follow this link: |
@minrk - are there any security ramifications of including the xsrf token in a link we are putting on the page, or making the xsrf token available from a function any extension can call? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well for me! We can revisit the xsrf approach later, but this fixes the behavior for the RC.
Edit: wrong PR.
Because we already put the |
@afshin - I just checked, and the xsrf cookie has a different value than the pageconfig token. |
ping @minrk again with the above question about how secure we should keep the xsrf token (see the changes in this PR for more context if you like) |
Everything on the page should/needs to have access to the xsrf token. Leaking xsrf tokens in authenticated requests is generally not an issue. The xsrf token serves to verify that information the page can control (the URL, extra headers) matches information that the page does not control (cookies). A single xsrf token value isn't useful. What would be useful is if a malicious page could retrieve the value of the xsrf cookie for the origin domain. Placing it in the page content for authenticated requests should not be a problem because the cross-site request fetching the page directly would get it with a different token value than the one sent to your browser with a forged request. A real cross-site vulnerability would be if the page contents with the xsrf token set by the current cookie could be retrieved and inspected by a cross-site request. Default cross-origin settings should prevent this. Still, FWIW, we should ensure that the notebook server doesn't include the xsrf token in logs if given as a url param (it probably does). This isn't a vulnerability per se, but it's always good to avoid logging tokens. |
I just checked - the notebook server does log the xsrf token given in a GET request. |
Some more investigations: It seems that:
In the cases above where I get a 403, I get this error in the server logs:
Interestingly, if I delete the download attribute, Chrome does send the referer header, and things work just fine even without the _xsrf query parameter, but of course the file replaces the lab page, which also doesn't work. My guess is that the real problem here has to do with https://bugs.chromium.org/p/chromium/issues/detail?id=455987, but Chrome only seems to be omitting the referer header with a link that has the download attribute set. From the above experiments, it seems that transmitting the _xsrf cookie but no referer header is not good enough. Only the _xsrf query parameter overrides a missing referer header. |
That's why #6139 removed the download attribute, which was a fix for this very issue. #6546 reverted that and reintroduced the problem. The comment in #6546 doesn't seem accurate, since the server sets content-disposition attachment, which triggers download instead of opening a new tab, at least in my testing. There's an explanation for this in #6139. |
To be clear, it's still fine to use the download attribute and xsrf query. This may be a more robust fix anyway.
The xsrf functionality requires the xsrf token to be sent twice with each request: in the cookie (browser controls) and via query parameter or extra X-XSRFToken header. For ajax, we use the xsrf header, but for links the query parameter must be used. This double-send is a verification that the crafter of the request had access to the token value set by the server in the cookie (or placed elsewhere in page data). The cookie alone doesn't work because cross-origin requests are still sent with cookies for the target site. But since the cross-origin page doesn't have access to the cookies for the other site, it can't craft a request with the xsrf token stored in the cookies duplicated to another field. And if the site made its own request for the page containing the xsrf token, it would get a different value from the one sent by your browser with your cookies. |
Thanks @minrk for the insights! |
@meeseeksdev backport to 1.0.x |
…6-on-1.0.x Backport PR #6686 on branch 1.0.x (Fix downloads in Chrome with xsrf token)
Thanks!
Makes sense! Thanks (again) for an explanation. |
References
#6658
Code changes
I removed
target=_blank
from the href created for downloading files because it:download
attribute is presentI added
?_xsrf=<token>
and a specified the file name in the download attribute to fix the download issues in Chrome. Chrome does not automatically determine the file name when the attribute is blank.