Skip to content
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

Outsource CSRF validation #38445

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kesselb
Copy link
Contributor

@kesselb kesselb commented May 24, 2023

Summary

To validate a CSRF token the Request object needs CsrfTokenManager.

CsrfTokenManager is a heavy dependency.

flowchart TD
    CsrfTokenManager
    CsrfTokenManager-->CsrfTokenGenerator-->ISecureRandom
    CsrfTokenManager-->SessionStorage-->ISession-->IUserSession
    IUserSession-->OC\User\Session
    OC\User\Session-->OC\User\Manager
    OC\User\Session-->OCP\ISession
    OC\User\Session-->ISecureRandom
    OC\User\Session-->LoggerInterface
    OC\User\Session-->IEventDispatcher
    OC\User\Manager-->ICacheFactory-->ICache

TODO

Checklist

@kesselb kesselb added the 2. developing Work in progress label May 24, 2023
apps/dav/lib/Server.php Fixed Show fixed Hide fixed
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 66b78c5 to 67a7fab Compare May 24, 2023 19:56
@kesselb kesselb changed the title Dept remove csrf dependency from request Outsource CSRF validation May 24, 2023
Copy link
Member

@tcitworld tcitworld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would refactoring OC\AppFramework\Http\Request::passesCSRFCheck to use the new CsrfValidator create more dependency hell? It would avoid to have the logic in two different places.

@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 67a7fab to ac0652e Compare May 25, 2023 16:56
@kesselb
Copy link
Contributor Author

kesselb commented May 25, 2023

It would avoid to have the logic in two different places.

I agree, having the logic in two different places it not an improvement.

The goal is to remove passesCSRFCheck and the CSRFTokenManager from IRequest.
I deprecated it, but it's public api and has to stay for 3 years major releases.

@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from ac0652e to 3cb076e Compare May 25, 2023 20:33
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 3cb076e to 6830563 Compare June 26, 2023 12:30
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from f806386 to 6f3ac85 Compare July 17, 2023 18:52
@kesselb kesselb self-assigned this Jul 17, 2023
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch 3 times, most recently from ca94de7 to 4ba5a0e Compare August 15, 2023 17:04
@kesselb kesselb added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Aug 15, 2023
@kesselb kesselb added this to the Nextcloud 28 milestone Aug 15, 2023
@nickvergessen
Copy link
Member

But now all the classes need CsrfValidator and that still needs CsrfTokenManager?
Or did I miss the point?

@kesselb
Copy link
Contributor Author

kesselb commented Aug 15, 2023

But now all the classes need CsrfValidator and that still needs CsrfTokenManager?

That's correct.

IRequest.passesCSRFCheck is only needed in a couple of places, but IRequest is injected in many more classes.
For Nextcloud 30, we can remove passesCSRFCheck and CsrfTokenManager from Request.

@kesselb
Copy link
Contributor Author

kesselb commented Aug 15, 2023

I'm having the idea of making IRequest lighter for a while now.

We are injecting an IRequest instance in a couple of places. For example, the logger. It makes sense, to include some details from the request object (e.g. request id, ip address, etc.) in our logs, but that requires a CsrfTokenManager instance and therefore a working database connection and cache. As soon as db or cache is unavailable, you can't use the logger anymore.

Examples:
#25770 (comment)
#37458 (comment)

@nickvergessen
Copy link
Member

For Nextcloud 30, we can remove passesCSRFCheck and CsrfTokenManager from Request.

3 years, not 3 versions xP so 36 😔

@nickvergessen
Copy link
Member

But okay, got it now and see how it improves.

Could also remove the dependency already and just depend on \OC::$server->get() for the time being? 😅

@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 4ba5a0e to fe647d5 Compare August 17, 2023 13:47
@kesselb
Copy link
Contributor Author

kesselb commented Aug 17, 2023

3 years, not 3 versions xP so 36 😔

😭

Could also remove the dependency already and just depend on \OC::$server->get() for the time being? 😅

Good idea 👍
I would like to do this as a follow-up.

@kesselb
Copy link
Contributor Author

kesselb commented Aug 17, 2023

@kesselb kesselb added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Aug 17, 2023
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 832af79 to 718c25f Compare August 30, 2023 20:01
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch 2 times, most recently from 877f6fd to 807fd72 Compare August 30, 2023 20:08
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 807fd72 to 079df3c Compare September 22, 2023 16:02
@kesselb kesselb added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Sep 22, 2023
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 079df3c to 57dbd17 Compare September 29, 2023 21:37
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 57dbd17 to 8de8409 Compare October 10, 2023 08:20
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
@kesselb kesselb force-pushed the dept-remove-csrf-dependency-from-request branch from 8de8409 to cddd9ba Compare October 17, 2023 17:44
@@ -201,6 +201,7 @@ public function getCookie(string $key);
*
* @return bool true if CSRF check passed
* @since 6.0.0
* @deprecated 28.0.0 use CsrfValidator.validate instead
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @deprecated 28.0.0 use CsrfValidator.validate instead
* @deprecated 28.0.0 use \OCP\Security\CSRF\ICsrfValidator::validate instead

*/
interface ICsrfValidator {
/**
* @since 28.0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description?


declare(strict_types=1);

namespace OCP\Security\CSRF;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
namespace OCP\Security\CSRF;
namespace OCP\Security\Csrf;

maybe

https://stackoverflow.com/questions/2236807/java-naming-convention-with-acronyms

@ChristophWurst ChristophWurst added the pending documentation This pull request needs an associated documentation update label Oct 17, 2023
@skjnldsv skjnldsv mentioned this pull request Nov 1, 2023
This was referenced Nov 6, 2023
@kesselb kesselb modified the milestones: Nextcloud 28, Nextcloud 29 Nov 14, 2023
@kesselb
Copy link
Contributor Author

kesselb commented Nov 14, 2023

Moving to 29

This was referenced Mar 12, 2024
This was referenced Mar 20, 2024
@skjnldsv skjnldsv mentioned this pull request Mar 28, 2024
81 tasks
@skjnldsv skjnldsv modified the milestones: Nextcloud 29, Nextcloud 30 Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review Waiting for reviews pending documentation This pull request needs an associated documentation update technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants