-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
In auto mode, cookie_secure
may not be set properly in a secure environment if session starts too soon
#40221
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
Comments
I suppose you can't register your authenticator after SessionListener? How would you recommend fixing this? Would you mind sending a PR (on branch 4.4)? |
I think fixing that would require changing the way the
|
the SessionListener runs at priority 128, which means that it already runs way before the guard authenticator (the firewall runs at priority 8) |
Thanks @stof for the suggestion. I am not very familiar with the internals, so I honestly I don't have any concrete idea on working on a fix. I have done what @stof has suggested in the PR. The code works fine, there is just one thing that bothers me. In the PR I am hard-coding to skip the 'auto' value in HttpFoundation's NativeSessionStorage, which I am not sure if this is a good solution because HttpFoundation can work independently, and this 'auto' value sounds a bit Symfony specific to me. Should I manipulate the default configuration that is passed to the constructor of NativeSessionStorage in the DI code instead? (I am not sure if this is possible, and if yes I'd probably need help on this.) |
…mcy) This PR was merged into the 4.4 branch. Discussion ---------- [HttpKernel] Configure `session.cookie_secure` earlier | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #40221 | License | MIT | Doc PR | N/A This PR does what @stof had suggested in #40221, allow me to quote him directly: > 1. avoid setting auto as a value for the ini setting in the NativeSessionStorage initialization > 2. ensuring that SessionListener resolves the auto value by the time the SessionListener runs, and not by the time the getSession() method is called in the Request session factory callback Commits ------- e82918c [HttpKernel] Configure `session.cookie_secure` earlier
Setting Symfony version 5.3.16 |
Uh oh!
There was an error while loading. Please reload this page.
Symfony version(s) affected: 4.4.19
Description
Recently I stumbled upon an issue that PHP isn't writing my cookie as "secure" in the output even when I
session.cookie_secure
explicitly set to "On" inphp.ini
, andcookie_secure
set toauto
in Symfony 4.4 (which is the default).I found this weird, because
sendHeaders()
method in Symfony'sResponse
object, so obviously Symfony knows it is a secure connection,cookie_secure
totrue
inframework.yaml
.After several hours of debugging, I have tracked down the cause. Here's how it happens:
NativeSessionStorage
is created, it calls ini_set() to replace the session-related configurations with those defined in the framework config. The values are written as-is, so whencookie_secure
is set toauto
inframework.yaml
, thisauto
will be passed toini_set
. Here's the problem -auto
is not a valid value for this configuration, and will probably be treated asOff
orFalse
. Which is why havingsession.cookie_secure
set to "On" inphp.ini
won't help in my situation.auto
normally won't stay forever. The problem is fixed bySymfony\Component\HttpKernel\EventListener\SessionListener
, which is activated when the framework'scookie_secure
is set toauto
.SessionListener
checks if the request is a secure one and if yes, it sets thecookie_secure
PHP option to true, thus overriding the previous incorrect value that will be intepretated asfalse
.Here is the tricky part. The reason the session ID cookie isn't properly written as
secure
even when the website is accessed through HTTPS is because in the frontend, I have an Authenticator that checks for a specific session key in thesupports
method. This method is executed so early in the request cycle such that the session is started beforeSessionListener
is run. When this happens, it is too late forSessionListener
to set thecookie_secure
PHP option totrue
because NativeSessionStorage's setOption() will exit immediately if the session has been started. Now theauto
value will stay till the end, which I believe will be treated asfalse
by PHP, so the PHPSESSID's cookie will not have thesecure
attribute.I don't see any warning that one should not access the session in the guard authenticator's
supports()
method. In fact I can find suggestion of "only return true in supports() if the user is on the correct URL and if that session key exists" in the comment section of a SymfonyCasts page, which is exactly what I was doing (the website I work on contains a frontend and backend which operate with different authenticators, and I need a bridge between them, thus the need for checking a particular session value). So I believe I am not doing something unwise.I understand that I may have stumbled upon an edge case, and probably not much people will be affected by this. Also it's not difficult to work around this problem, I just need to defer the session checking until
getUser()
is called. Or I can just explicitly setcookie_secure
totrue
to avoid this glitch. But since the consequence is security related (cookie_secure
flag is not turned on even when it should), I think it would be better for me to report this issue anyway and mark it as a bug report first and let your team decide what to do with it.Thank you!
Update 19 Feb
After some more tests, it looks like the problem is probably a more wide-spreaded one.
session.cookie_secure
isn't set properly (i.e. stays in "auto") even for the following controller code in a newly set up Symfony 4.4 and 5.2 project:The text was updated successfully, but these errors were encountered: