The NoSessionOpen RequestPolicy (Drupal\Core\PageCache\RequestPolicy\NoSessionOpen) returns static::ALLOW when the user is not logged in. In my opinion it should also return static::DENY when the user is already logged in, to prevent logged in pages to come up in the cache.
We created a custom page cache policy that returned a ALLOW and a DENY and found out that logged in pages were being served to anonymous users. This can all be fixed by returning DENY from the NoSessionOpen Policy.
Comment | File | Size | Author |
---|---|---|---|
#4 | 2829892-4-deny-page-cache-NoSessionOpen.patch | 1.11 KB | jeroen.b |
#2 | 2829892-deny-page-cache-NoSessionOpen.patch | 525 bytes | jeroen.b |
Comments
Comment #2
jeroen.b CreditAttribution: jeroen.b at .VDMi/ commentedComment #4
jeroen.b CreditAttribution: jeroen.b at .VDMi/ commentedFix for tests.
Comment #5
Wim LeersPlease write a test proving that "logged in pages" are being stored in Page Cache. I cannot reproduce this. If you can, this is a critical security issue.
Comment #6
jeroen.b CreditAttribution: jeroen.b at .VDMi/ commented@Wim Leers, this is only a problem when you implement a custom RequestPolicy that always returns a DENY or ALLOW.
Comment #7
Wim LeersAha! Adjusting title accordingly.
That suggests that
\Drupal\Core\PageCache\ChainRequestPolicy::check()
needs hardening. HardeningNoSessionOpen
is pointless, because another request policy can then have the exact same "weakness". Hardening\Drupal\Core\PageCache\ChainRequestPolicy::check()
would fix it in all request policies at once.Right?
Comment #8
alexpottLooks like we have the more info. But
So NULL was part of the design.
@Wim Leers so what hardening where you thinking of?
Comment #9
jeroen.b CreditAttribution: jeroen.b at .VDMi/ commentedI don't think so. When one Policy says
DENY
, then nothing get's through.So when
NoSessionOpen
always returnALLOW
orDENY
, it should be fixed.I think the main problem is that there is no Policy saying
DENY
right now.Comment #10
Wim Leers@alex.pott: hardening to prevent the problem that @jeroen.b described from also causing problems in request policies in contrib/custom modules.
Comment #12
znerol CreditAttribution: znerol commentedI see that the documentation around page cache request/response policies is far from complete. Sorry for that.
I try to clarify the meaning of the three possible results of a request policy rule:
The combination of multiple rules follows common sense: The result is
DENY
if any rule returnedDENY
and it isNULL
unless at least one rule returned ALLOW - then it is obviouslyALLOW
.It follows that a policy rule should be designed in a way that it either returns
ALLOW|NULL
orDENY|NULL
. A rule returningALLOW|DENY
cannot be combined in any useful way with other policy rules.We have the following request policy rules in core:
The notable allow examples are
NoSessionOpen
andAllowToolbarPath
, the relevant deny-rule isCommandLineOrUnsafeMethod
. TheChainRequestPolicy
let's us combine all the rules.NoSessionOpen
returnsALLOW
if there is no session on the request, it returnsNULL
otherwise.AllowToolbarPath
returnsALLOW
if the path matches thetoolbar/subtree
route and returnsNULL
otherwise. The combination of those two policy rules results in anALLOW
for any request which is either session-less or directed to the toolbar subtree endpoint. By addingCommandLineOrUnsafeMethod
to the mix we additionally require the request to be either HTTPGET
orHEAD
.Does that make sense?