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

[RTM] Store the request token as cookie instead of the session #1065

Merged
merged 12 commits into from
Sep 28, 2017

Conversation

ausi
Copy link
Member

@ausi ausi commented Sep 11, 2017

Use a double submit cookie instead of storing the request token in the session of the user.

@ausi ausi force-pushed the feature/double-submit-cookie branch 2 times, most recently from a0b0742 to 93b65a0 Compare September 11, 2017 20:25
*
* @return array
*/
public function getSaveTokens()
Copy link
Member

Choose a reason for hiding this comment

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

I don't like this method name, shouldn't it be getActiveTokens if the internal variable is called $activeTokens? Also, I would prefer to name that usedTokens 😁

The method can be simplified like this:

return array_intersect_key($this->tokens, $this->activeTokens);

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in c3f6afb

* @param int $cookieLifetime
* @param string $cookiePrefix
*/
public function __construct(MemoryTokenStorage $tokenStorage, int $cookieLifetime = 86400, string $cookiePrefix = 'csrf_')
Copy link
Member

Choose a reason for hiding this comment

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

Does this have to be a MemoryTokenStorage? Shouldn't we expect the interface?

Copy link
Member Author

Choose a reason for hiding this comment

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

We call the initialize() method on it, so we cannot use the interface.

$tokens = [];

foreach ($cookies as $key => $value) {
if (strncmp($key, $this->cookiePrefix, strlen($this->cookiePrefix)) === 0) {
Copy link
Member

Choose a reason for hiding this comment

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

strpos($this->cookiePrefix, $key) === 0 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

strncmp() should be way faster IMO.

- "@contao.csrf.token_storage"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 20 }
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse, priority: 0 }
Copy link
Member

Choose a reason for hiding this comment

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

you don't need to set a priority if it's 0.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in d874349

@ausi ausi changed the title [WIP] Store the request token as cookie instead of the session [RFC] Store the request token as cookie instead of the session Sep 12, 2017
@leofeyer leofeyer added this to the 4.5.0 milestone Sep 12, 2017
$isSecure = $event->getRequest()->isSecure();

foreach ($this->tokenStorage->getUsedTokens() as $key => $value) {
$event->getResponse()->headers->setCookie(
Copy link
Member

Choose a reason for hiding this comment

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

I think you should use deleteCookie if the value is null. This way Symfony handles the unset case.

Copy link
Member Author

Choose a reason for hiding this comment

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

deleteCookie needs the same arguments as setCookie, except value and lifetime. Using deleteCookie would make a block of duplicate code.

Copy link
Member

Choose a reason for hiding this comment

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

but it would move the delete logic to the header bag instead of our class, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you refer to $value === null ? 1 : $cookieLifetime as the delete logic, then yes.

Copy link
Member

@Toflar Toflar left a comment

Choose a reason for hiding this comment

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

Looks good to me, can you add an issue to the header-replay-bundle so I can work on what's needed to make sure that cookie is ignored from executing a preflight request?

@leofeyer leofeyer changed the title [RFC] Store the request token as cookie instead of the session [RTM] Store the request token as cookie instead of the session Sep 18, 2017
@leofeyer leofeyer force-pushed the develop branch 5 times, most recently from ed0a7e5 to 3dadd44 Compare September 28, 2017 10:39
@leofeyer leofeyer force-pushed the feature/double-submit-cookie branch 2 times, most recently from 0e0a15f to b142160 Compare September 28, 2017 14:52
@leofeyer leofeyer merged commit 47a2e6a into contao:develop Sep 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants