The flag reload link needs a token, otherwise it is vulnerable to attacks.

For example, an attacker could craft a link to flag or unflag an entity, and use that URL as the SRC property for an image elsewhere on the web, or indeed in something such as an email. A user's browser would then attempt to load that image, and in doing so, cause a flagging action on the site on behalf of the unsuspecting user.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joachim’s picture

Status: Active » Needs review
Issue tags: +Needs tests
FileSize
5.58 KB
6.1 KB

1-line fix to add tokens to a link! Nice!

We need tests for this, and as it turns out the reload link type has no coverage, here's a whole new test class.

In addition to checking the lifecycle of the flagging, we try to load the reload link without the token and check we get access denied.

Status: Needs review » Needs work

The last submitted patch, 1: 2466703-1.flag_.reload-link-token.patch, failed testing.

The last submitted patch, 1: 2466703-1.flag_.reload-link-token-tests-only.patch, failed testing.

Berdir’s picture

Hm. This is going to be a problem with caching. The node is going to be cached including the csrf_token.

Try to test this with two different users, access it with the first user, then the second, the link won't work for that one. Maybe we already have some tests that proof this?

Fixing this is tricky, maybe post_render_cache? See #2467425: As a temporary measure until we have cacheable CSRF: let all forms add a csrf_token cache context?, but if we vary the cache for the flag/node for every user, then we're pretty much killing the node render cache. That's not cool.

Berdir’s picture

Good, we do have tests for exactly that :) Might be easier to just add some additional asserts there for this?

Berdir’s picture

wrong issue.

joachim’s picture

Aw that's a pain :(

But then this is a problem in Flag with the reload link in 7x-3x, and indeed ever since it was introduced (or as long as Drupal core has had a page cache).

So we could legitimately fix the security regression, then slap on a warning on the UI description of the link to say don't use it with caching, and then think about how to fix the caching. Another possibility is offering an option to disable the token -- we've had several requests over the years to have this feature on 7x-3x.

Berdir’s picture

Well, page cache is one thing, but D8 has a lot more caching, as you can see, it's failing for authenticated users. And you can't disable that. Or don't want to. Because without render cache, D8 would be *very* slow.

I'll ask WimLeers, maybe he has some ideas.

joachim’s picture

Another issue asking to have the token turned off in D7: #2470373: How to bypass or alter CSRF token for a certain flag...

joachim’s picture

Title: Flag reload link is missing a token » Flag reload and AJAX link types are missing a token

This affects the AJAX links too; the same attack could be crafted with that link type too.

Is there any way to have placeholders in the cached rendered content, which are replaced on output?

Berdir’s picture

Yes, there's the render cache that we can use but that won't work for anonymous users. Not completely sure if the csrf token access check is intelligent enough to skip them. Based on a quick look, apparently not...

joachim’s picture

On earlier versions of Flag, anonymous users aren't allowed to access flag at all unless Session API module is present.

joachim’s picture

So now we've set a cache context with #2473921: FlagSimpleTest is failing due to render/page caching, can the need for a token be handled by changing the cache context to:

$build['#cache']['contexts'][] = 'user'

so the entity is cached per-user?

Though making the whole entity cached per-user is not brilliant for performance...

Berdir’s picture

See #2565501-3: Tests are not working because Dynamic page cache was committed in core.. No, the user cache context doesn't help since a user can flag or unflag a node and then it has to change. And as you said, it would be very bad for performance.

Berdir’s picture

Status: Needs work » Needs review
FileSize
6.09 KB

Core now builds those tokens by default in a post render cache. Which means that this might just work now. Lets try. Simple rebase, the tests might need some updates now.

Status: Needs review » Needs work

The last submitted patch, 15: 2466703-15.flag_.reload-link-token.patch, failed testing.

Berdir’s picture

FlagSimpleTest doesn't fail on this anymore, so that seems to actually work now. Didn't look into the new test fails.

tduong’s picture

Status: Needs work » Needs review
FileSize
7.17 KB
2.98 KB

Uploaded patch

  • fixed FlagLinkReloadTest
  • fixed "@views-url" (in FlagListBuilder) needed because of an exception in FlagLinkReloadTest
joachim’s picture

Well spotted!

However, this fix belongs in a new issue. And the whole of that stuff should be removed, as Views module is now in core, so you can't download it, and I don't think we need to tell people they can use Views to make lists.

+++ b/src/Controller/FlagListBuilder.php
@@ -105,7 +105,8 @@ class FlagListBuilder extends DraggableListBuilder {
+      // Fixed "@views-url" needed because of an exception in FlagLinkReloadTest.

BTW: we don't put comments code about the changes that have been made. Comments should be about the code now. For everything else, there's the git log and the issue queue.

Berdir’s picture

I knew you'd say that :)

Agreed with removing that text, the only problem is that this test causes an error because of it, so if we make a separate issue for that, we have to postpone this (critical) issue on a normal bugfix. But yes, lets create a quick issue for removing that then.

joachim’s picture

It's a 5-minute fix -- I can take care of it after lunch today unless @tduong beats me to filing an issue and making a patch :)

joachim’s picture

Step one: created issue: #2619848: remove UI text about downloading Views.

(I'm not slacking off work, my caches are taking ages to clear ;)

tduong’s picture

Step two: patch uploaded for that issue :P

For this issue:

  • uploaded patch without the change in FlagListBuilder

This test will have to be retested after that the other issue will be committed

Status: Needs review » Needs work

The last submitted patch, 23: 2466703-23.flag_.reload-link-token.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

Green now :)

@joachim, You added the Needs Tests that and provided a patch with test in the same patch, I don't really understand why, isn't this enough test coverage?

The last submitted patch, 18: 2466703-18.flag_.reload-link-token.patch, failed testing.

The last submitted patch, 15: 2466703-15.flag_.reload-link-token.patch, failed testing.

joachim’s picture

Eh, that was back in April. I have no idea! I'd completely forgotten I wrote the tests too! :D

Though I see the test class needs a rename, as since I wrote that we've changed the link type tests to be called LinkTypeFOOTest. But given this is critical, that can be a follow-up.

tduong’s picture

Uploaded patch:

  • changed test class name as LinkTypeReloadTest
Berdir’s picture

Status: Needs review » Reviewed & tested by the community

-1 critical? :)

The last submitted patch, 18: 2466703-18.flag_.reload-link-token.patch, failed testing.

The last submitted patch, 15: 2466703-15.flag_.reload-link-token.patch, failed testing.

  • joachim committed 6d7683c on 8.x-4.x authored by Berdir
    Issue #2466703 by tduong, joachim, Berdir: Fixed missing token on reload...
joachim’s picture

Status: Reviewed & tested by the community » Fixed

Committed!

Thanks for that final reroll tduong :)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.