This a bit of a feature request/bug at the same time depending on what changed between 3.x and 4 as I did not experience this with 3.x
Joomla 4 and CloudFlare (Free - CNAME setup through hosting partner providers)
Login and navigate around for about 10 seconds, after that point the session gets destroyed. Subsequent logins are met with error/security message: “The security token did not match. The request was aborted to prevent any security breach. Please try again.”
Session should stay in effect for the duration specified unless event occurs to extend the timeframe
Sessions are destroyed in almost 10 seconds flat
Seems to work fine when CloudFlare bypassed
Joomla 4
PHP 7.4
It did work as expected in 3.x so I’m not sure if something was introduced in 4.0 that made the authentication stricter on what it checks to keep the session valid and active but if IP validation was added, while it is the most secure, it’s not the way to go anymore.
Labels |
Removed:
?
|
Labels |
Added:
No Code Attached Yet
|
Title |
|
Do you have the page caching enabled at Cloudflare?
I did but then I had it disabled and even tested it with development mode and sessions still get destroyed prematurely. After I disabled my caching page rule and tried development mode, I could get sessions to last for 60 seconds tops when idle. After that the session still gets destroyed.
On Aug 20, 2021, at 12:02 PM, Phil E. Taylor @.***> wrote:
Do you have the page caching enabled at Cloudflare?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFSDHOXW7I5JBVUE5FTT5Z373ANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
What is the url of the site you have on cloudflare?
https://www.mycoolweb.x10host.com/iconnect (just the www part since it is CNAME setup, without it you will be automatically redirected to the www).
I only have it set to US access, should be good to access now, just temporarily shut off the access firewall.
:status: 200
Content-Encoding: br
X-Content-Type-Options: nosniff
Link: </iconnect/templates/cassiopeia/css/global/colors_standard.min.css>; rel="prefetch"; as="style"
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Referrer-Policy: strict-origin-when-cross-origin
Vary: User-Agent
Date: Sun, 22 Aug 2021 17:24:43 GMT
Expires: Wed, 17 Aug 2005 00:00:00 GMT
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=utf-8
Last-Modified: Sun, 22 Aug 2021 17:25:24 GMT
x-powered-by: PHP/7.4.16
Server: cloudflare
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
Alt-Svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=q9%2BiFfn2CfuMdUdEVJbXSMcHSCLn7rWnAOjRP9e%2FnlJ0ydU2dUY%2Fft9Gyp1SfcP2W1jWDYKt%2FIwSTkURt97lwPUi3SXul74wA6xZ07ad4o%2FPvt6G1%2Bd8IW40BmISTeO6xvXGLxNLSNKpGuWSFLkwVGnWDnBgkBfZ"}],"group":"cf-nel","max_age":604800}
cross-origin-opener-policy: same-origin
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
cf-railgun: 3214b8f4ce stream 0.000000 0310 57da
cf-ray: 682dcbd69f21ee33-CDG
**cf-cache-status: DYNAMIC**
Well the cache status is not a HIT so the page is not cached. When I removed my cookie I received a new token, and if I reused my cookies then I received the same token. So no issue found here. It looks fine to me.
Although on my tests I did also see this header
X-Turbo-Charged-By: LiteSpeed
which probably means your webhost is also doing some crazy caching.
and
Cf-Railgun: direct (starting new WAN connection)
which means you are doing some manipulation of the request with CloudFlare's Railgun feature and caching the site closer to the end user.
Ultimately Im convinced now that this is not a core Joomla issue.
Not sure why Railgun was still on since it was disabled (to the point it would not function) since my host moved over to DirectAdmin but I did manage to shut it down and about to retest to see what happens.
What I don't necessarily get is how in 3.9 and 3.10, it was all fine at its current settings.
What I don't necessarily get is how in 3.9 and 3.10, it was all fine at its current settings.
I cannot test the past, I can only test what is presented at the time of the test :) but from everything you have said, including the fact you through railgun was off when its indeed on still, leads me further to belief that this is not a Joomla 4 issue.
Cloudflare is used by a high percentage of the internet sites - if there are multiple reports then we can look again, but at the moment your report is the only one.
Thanks for the help though. I’ll have to reach out to the host and see what weirdness LiteSpeed is doing since in turned Railgun off, and it persisted. This time I was finally able to replicate it by bypassing Cloudflare altogether.
Though I did make one change. I now have 3.10 and 4.0 running side by side on the same server. Tested 4.0 and 3.10 both set to the same session settings, and only 4.0 came back with an issue again. So when I reach out to my host, I’ll try to see if maybe they could figure out what weirdness on LiteSpeed is affecting 4.0 but leaving 3.10 unaffected.
Sent from my iPhone
On Aug 22, 2021, at 1:48 PM, Phil E. Taylor @.***> wrote:
What I don't necessarily get is how in 3.9 and 3.10, it was all fine at its current settings.
I cannot test the past, I can only test what is presented at the time of the test :) but from everything you have said, including the fact you through railgun was off when its indeed on still, leads me further to belief that this is not a Joomla 4 issue.
Cloudflare is used by a high percentage of the internet sites - if there are multiple reports then we can look again, but at the moment your report is the only one.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFTQ2B7STHVAP2CKO2TT6EZ5RANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
@PhilETaylor I can help - send to your email admin credentials of one my Joomla test site, which have same issue and you can test it.
And also credentials to my cloudflare account, if it necessary.
I'm also having the same issue. Also at Cloudflare
I've never had this issue before. Any advice or help would be much appreciated.
@sjb1963, do you know what your web server is running (LiteSpeed, Apache, Nginx, etc)?
On Aug 23, 2021, at 1:42 PM, sjb1963 @.***> wrote:
I'm also having the same issue. Also at Cloudflare
I've never had this issue before. Any advice or help would be much appreciated.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFRU23LOHIGQZAXDHEDT6KB7NANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
@jweaver0312
I am on Amazon Lightsail with RunCloud
It's an Apache/NGiNX hybrid.
If you bypass cloudflare, does it do the same thing, when dealing with the origin?
Sent from my iPhone
On Aug 23, 2021, at 1:59 PM, sjb1963 @.***> wrote:
@jweaver0312https://github.com/jweaver0312
I am on Amazon Lightsail with RunCloud
It's an Apache/NGiNX hybrid.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFQCLY2QXNIMGDRD3ODT6KD6VANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
@jweaver0312
When I switch DNS to "DNS ONLY" I get the expected really nasty security message
And my session survives.
With your session surviving and cloudflare bypassed, leave it idle for 5-10 minutes and try navigating though again to see if it really stays.
Sent from my iPhone
On Aug 23, 2021, at 2:06 PM, sjb1963 @.***> wrote:
@jweaver0312https://github.com/jweaver0312
When I switch DNS to "DNS ONLY" I get the expected really nasty security message
And my session survives.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFUHDP774PVF2SWZKYDT6KE3VANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
Let me say again - Cloud Flare Caches... thats what its designed to do. If you cache a token, it will be cached. when you try to use the form and generate a POST, it will not use a valid token, it will use the cached token in the HTML.
Disable ALL CACHING and then forms will work.
That is what I did on mine and it still persists even though I’m on LiteSpeed being a similar hybrid.
When LiteSpeed and Cloudflare were leaving 3.10 alone and only affecting 4.0 only (which I have just tested now that I have them side by side on the same server) that makes me point the finger the other way.
Sent from my iPhone
On Aug 23, 2021, at 2:08 PM, Phil E. Taylor @.***> wrote:
Let me say again - Cloud Flare Caches... thats what its designed to do. If you cache a token, it will be cached. when you try to use the form and generate a POST, it will not use a valid token, it will use the cached token in the HTML.
Disable ALL CACHING and then forms will work.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFWYADQF3DMNPMHFXTLT6KFCJANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
@jweaver0312
I misunderstood you earlier.
Yes, when I put it in Development mode, the issue persists. The only time it doesn't is when I turn the proxy off in DNS, and of course that removes the SSL references.
I am using "Full Strict" in SSL.
I have installed the certificate they generate on the server.
I don't know how much any of this has to do with anything, but it's weird, so there you go :)
Yes Sir :) I have done that. (currently set that way, but I've tried it both ways)
I have the same problem, it had already happened to me with the beta versions and I thought it would be solved with the stable version. I tried everything and I haven't found the solution.
Just a follow up, Joomla 4.01 did not resolve this.
of course it didn't, no one has worked on this issue yet. Hence why its still open.
But by upgrading to Joomla 4.0.1 you have introduced a bug that means you cannot upgrade to Joomla 4.0.2 - please ensure you read the media/docs surrounding the upcoming 4.0.2 release to fix this, so that you will be able to upgrade again.
Thanks Phil! I will do that.
Version 4.0.2 didn't solve the problem either.
Version 4.0.2 didn't solve the problem either.
Of course it didn't. 4.0.2 was only released to resolve an issue with the com_joomlaupdate that I broke. No other bug fixes were added.
As Cloudlare acts as a proxy, I think the Enable Proxy Output should be actived, BUT, it asks for proxy hosts, port and credentials what are unknown for us.
As Cloudlare acts as a proxy, I think the Enable Proxy Output should be actived, BUT, it asks for proxy hosts, port and credentials what are unknown for us.
No.
Outbound proxy is FROM YOUR SITE to a proxy server and then out to sites like extension update sites. This is useful if you are running an intranet on a corporate network that needs proxy access to access the internet.
INBOUND proxy is what Cloudflare is.
Hello,
I'm working on 2 new websit with Joomla 4 but it is impossible to do it, the session expires every 60 seconds! I'll do with Joomla 3.
I'm using CloudFlare and hosting is SupportHost to which I have opened a ticket to report this problem.
I have more then 30 other sites with Joomla 3 on the same hosting (and setting) and this problem has never been seen. Tell me what you want but for me it is a problem related to Joomla 4 which needs to be resolved urgently.
Whatever the cause one would expect the session to last as set in the configurations.
Here my bug report: https://issues.joomla.org/tracker/joomla-cms/35495
Best regards
Marco
If anyone is able to donate a non-live non-customer website that has this specific problem (sessions when run though cloud flare) on a site that reproduces the problem each and every time, please can you provide (securely through the encrypted form) your site credentials at https://fix.mySites.guru/now so that I might investigate this issue (For FREE there is no charge) so that we can understand what exactly is happening on a technical level (other than "it doesnt work" and "I get logged out" :-))
I have some time this week to dedicate to this.
Sent credentials
Sent credentials
No, you failed to follow the instructions and so sent your email through insecure contact form instead of the secure and GPG encrypted process at https://fix.mySites.guru/now - you only sent your Joomla Admin credentials whereas the form at https://fix.mySites.guru/now would have collected the full set of data required to gain full and unrestricted access, including FTP, so that I can actually replicate and debug instead of just being able to say "yup I see the same as you" which is no help in resolving the problem. :-)
Login and navigate around for about 10 seconds, after that point the session gets destroyed.
I have been navigating around now for 4 mins... and Im still logged in with not a single session being destroyed on me.
Websites like this should be abandoned on principle! grrrr
Disabled Functions | getmyuid,passthru,leak,listen,diskfreespace,tmpfile,link,ignore_user_abort,shell_exec,dl,set_time_limit,exec,system,highlight_file,source,show_source,fpassthru,virtual,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,proc_open,proc_close,proc_nice,proc_terminate,escapeshellcmd,ini_alter,popen,pcntl_exec,socket_accept,socket_bind,socket_clear_error,socket_close,socket_connect,symlink,posix_geteuid,ini_alter,socket_listen,socket_create_listen,socket_read,socket_create_pair,stream_socket_server |
---|
Your Session Save path is:
/home/runcloud/something/somethingelse/public_html/tmp
This means whenever Joomla, or other tools, cleans up the tmp folder... it will delete session data!!!
Also this means your session data is available on the web - bar the fact you are lucky and have a .htaccess that stops access to /tmp...
you should NEVER set your session store to be in your public webspace, this should be handled by the server configuration correctly and not per site.
Websites like this should be abandoned on principle! grrrr
Disabled Functions getmyuid,passthru,leak,listen,diskfreespace,tmpfile,link,ignore_user_abort,shell_exec,dl,set_time_limit,exec,system,highlight_file,source,show_source,fpassthru,virtual,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,proc_open,proc_close,proc_nice,proc_terminate,escapeshellcmd,ini_alter,popen,pcntl_exec,socket_accept,socket_bind,socket_clear_error,socket_close,socket_connect,symlink,posix_geteuid,ini_alter,socket_listen,socket_create_listen,socket_read,socket_create_pair,stream_socket_server
Maybe the hosted should disable php...
Websites like this should be abandoned on principle! grrrr
Disabled Functions getmyuid,passthru,leak,listen,diskfreespace,tmpfile,link,ignore_user_abort,shell_exec,dl,set_time_limit,exec,system,highlight_file,source,show_source,fpassthru,virtual,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,proc_open,proc_close,proc_nice,proc_terminate,escapeshellcmd,ini_alter,popen,pcntl_exec,socket_accept,socket_bind,socket_clear_error,socket_close,socket_connect,symlink,posix_geteuid,ini_alter,socket_listen,socket_create_listen,socket_read,socket_create_pair,stream_socket_server
So without context, "sites like this" is not helpful.
My comment here #35244 (comment) is more likely your root issue.
Im still logged in all this time - my session has not been destroyed once yet...
Just got logged out a few times in a row. Actually #35244 (comment) is not going to be your root cause because the session data is in the database, and Joomla is not using files for session storage here...
I send now my data to use this website installation where session expire after 60".
Hosting support check now and don't detect problem on this server.
Best regards
Marco
Thanks I’m in bed now but will take a look tomorrow to see if I can find any causes
The session for my site is via database and in less than 1 minute, if I try to save something or if I don't navigate, I get logged out.
Why J3 works like a charm while J4 has a lot of issues with the sessions?
So, here is the root issue
What is happening is, I login, and as loing as I continue to browse quickly moving through pages, my session is being handled by one of the cloudflare ray nodes (evidenced by the Response header: cf-ray: 68b7a2854e62cdb3-CDG)
If I go for a coffee, or just wait a few mins and then try to navigate to a new page then my computer connects to a different Cloudflare ray node (as evidenced by the response header cf-ray: 68b7b6ad1b0f39ab-CDG)
As CloudFlare is nothing other than a reverse proxy (ok, with a few bells and whistles), CloudFlare requests as seen by Joomla look like any other proxied requests, and the $_SERVER['REMOTE_ADDR']
is the CloudFlare Proxy Server address and NOT the IP address of my computer (or more correctly, my public IP address). My real IP is pushed into several other headers ("2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
in the examples below is my real IP)
Here is an example of the request headers sent to a Joomla site by Cloudflare (Ive manipulated slightly to prevent you seeing my real ipv6 etc)
"Host" => "example.com"
"X-Real-IP" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"X-Remote-IP" => "108.162.229.27"
"Accept-Encoding" => "gzip"
"cf-ipcountry" => "JE"
"X-Forwarded-For" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"cf-ray" => "68b7bd27094a3317-CDG"
"x-forwarded-proto" => "https"
"cf-visitor" => "{"scheme":"https"}"
"Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"
"Accept-Language" => "en-GB,en;q=0.9"
"Cookie" => "0e271dc10c723185f1bb6c8ab5fca21b=4e15f8f87709624da62afc4a352afc8d"
"cf-connecting-ip" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"cdn-loop" => "cloudflare"
"Content-Length" => "0"
This is converted by PHP to a $_SERVER
global array like this (again slightly modified by me)
array:47 [▼
"PATH" => "/usr/local/bin:/usr/bin:/bin"
"TEMP" => "/tmp"
"TMP" => "/tmp"
"TMPDIR" => "/tmp"
"PWD" => "/"
"HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
"HTTP_ACCEPT_ENCODING" => "gzip"
"HTTP_ACCEPT_LANGUAGE" => "en-GB,en;q=0.9"
"CONTENT_LENGTH" => "0"
"HTTP_COOKIE" => "0e271dc10c723185f1bb6c8ab5fca21b=4e15f8f87709624da62afc4a352afc8d"
"HTTP_HOST" => "example.com"
"HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15"
"HTTP_X_FORWARDED_FOR" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"HTTP_X_REAL_IP" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"HTTP_X_REMOTE_IP" => "108.162.229.27"
"HTTP_CF_IPCOUNTRY" => "JE"
"HTTP_CF_RAY" => "68b7bd27094a3317-CDG"
"HTTP_X_FORWARDED_PROTO" => "https"
"HTTP_CF_VISITOR" => "{"scheme":"https"}"
"HTTP_CF_CONNECTING_IP" => "2a02:c28:FACE:FACE:FACE:FACE:FACE:2e2e"
"HTTP_CDN_LOOP" => "cloudflare"
"UNIQUE_ID" => "YTiafCZInhA1Ej6fdUzPsgAABco"
"SCRIPT_URL" => "/headers.php"
"SCRIPT_URI" => "http://example.com/headers.php"
"SERVER_SIGNATURE" => ""
"SERVER_SOFTWARE" => "Apache"
"SERVER_NAME" => "example.com"
"SERVER_ADDR" => "88.88.88.88"
"SERVER_PORT" => "80"
"REMOTE_ADDR" => "108.162.229.27"
"DOCUMENT_ROOT" => "/home/ttfyouvb/example.com"
"REQUEST_SCHEME" => "http"
"CONTEXT_PREFIX" => ""
"CONTEXT_DOCUMENT_ROOT" => "/home/ttfyouvb/example.com"
"SERVER_ADMIN" => "phil@phil-taylor.com"
"SCRIPT_FILENAME" => "/home/ttfyouvb/example.com/headers.php"
"REMOTE_PORT" => "41582"
"SERVER_PROTOCOL" => "HTTP/1.1"
"REQUEST_METHOD" => "GET"
"QUERY_STRING" => ""
"REQUEST_URI" => "/headers.php"
"SCRIPT_NAME" => "/headers.php"
"PHP_SELF" => "/headers.php"
"REQUEST_TIME_FLOAT" => 1631099516.0671
"REQUEST_TIME" => 1631099516
"argv" => []
"argc" => 0
]
As you can see $_SERVER['REMOTE_ADDR']
is a ipv4 (even though Im personally connecting to CloudFlare with ipv6), and has a value of 108.162.229.27
which is the CloudFlare ray proxy address Joomla is seeing.
Now, the problem is that if I come back in 10 mins (or even 60 seconds after being idle) this REMOTE_ADDR
value will change.
However, Joomla CMS layers use the joomla-framework/utilities package to detect the correct IP - and if you have correct set the "Behind Loadbalancer" configuration in Joomla Global Configuration, then that package will return the value of HTTP_X_FORWARDED_FOR
and not the value for REMOTE_ADDR
- which is the correct process (I know, because I recently fixed a security issue with this feature).
HOWEVER, Joomla 4 CMS layer, also uses the joomla-framework/session package to handle session management, and within that package there is a hardcoded call to $remoteAddr = $this->input->server->getString('REMOTE_ADDR', '');
this is the root of all the evil, because, as I have pointed out above, once CloudFlare uses a different ray proxy, the REMOTE_ADDR
will change... and because the joomla-framework/session package @2.0-dev is so strict (for security reasons) and is unaware of the Joomla CMS Layer allowing "Behind Loadbalancer" configuration (more specifically allowing IP Overrides, the use of HTTP_X_FORWARDED_FOR
instead of using REMOTE_ADDR
), it then goes on to check if the current REMOTE_ADDR
is the same as the IP address that started the session (earlier in the day) and because they dont match, BANG!!!! it throws an exception (which is silently caught and replaced with a FALSE
), which in turn starts a new session and you are logged out....
Therefore the fix for this lies deep in the joomla-framework/session package, which needs to become aware of the Joomla CMS layer's configuration to allow IP Overides (the use of HTTP_X_FORWARDED_FOR
(and others) when behind a proxy and not just blindly use REMOTE_ADDR
)...
here:
And breath....
Now on to taking questions:
The session for my site is via database and in less than 1 minute, if I try to save something or if I don't navigate, I get logged out.
Because your IP Address in REMOTE_ADDR
has changed, as you are now using a different CloudFlare Proxy server. Not your choice. And because joomla-framework/session is hard coded (incorrectly) to use the REMOTE_ADDR
when checking for session security.
Why J3 works like a charm while J4 has a lot of issues with the sessions?
Because Joomla 4 uses a more secure session management solution. And its not "a lot of issues" its one issue with one cause and only when used behind a proxy such as CloudFlare. Lets keep this in context.
This now probably needs @wilsonge and @nibra to decide what the correct fix to apply is.
The solution is probably
Thanks for investigating all of this
@PhilETaylor
Thank you very much for the analysis.
Considering the problem, a work around can be deactivated CloudFlare (from the DNS section) waiting for the definitive solution?
Yesterday I tried to activate CloudFlare "developer mode" and it did not produce results, maybe with the DNS bypass the problem is buffered?
I do not believe putting CloudFlare into dev mode would "fix this" as the documentation https://developers.cloudflare.com/cache/reference/development-mode only says
Development Mode temporarily suspends Cloudflare's edge caching, minificationOpen external link, Polish, and RailgunOpen external link features for three hours unless disabled beforehand. Development Mode allows customers to immediately observe changes to their cacheable content like images, CSS, or JavaScript.
and caching is not the problem here.
For those that would like to try - please apply these changes to your site and see if this fixes the issue for you (note: YOU DO STILL NEED the Behind LoadBalancer option enabled in Joomla Global Config)
If you dont know how to read a diff, try this, EDIT the file
libraries/vendor/joomla/session/src/Validator/AddressValidator.php
and replace the content of that file with this:
<?php
/**
* Part of the Joomla Framework Session Package
*
* @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
namespace Joomla\Session\Validator;
use Joomla\Input\Input;
use Joomla\Session\Exception\InvalidSessionException;
use Joomla\Session\SessionInterface;
use Joomla\Session\ValidatorInterface;
use Joomla\Utilities\IpHelper;
/**
* Interface for validating a part of the session
*
* @since 2.0.0
*/
class AddressValidator implements ValidatorInterface
{
/**
* The session object.
*
* @var SessionInterface
* @since 2.0.0
*/
private $session;
/**
* Constructor
*
* @param Input $input The input object
* @param SessionInterface $session DispatcherInterface for the session to use.
*
* @since 2.0.0
*/
public function __construct(Input $input, SessionInterface $session)
{
$this->session = $session;
}
/**
* Validates the session
*
* @param boolean $restart Flag if the session should be restarted
*
* @return void
*
* @since 2.0.0
* @throws InvalidSessionException
*/
public function validate(bool $restart = false): void
{
if ($restart)
{
$this->session->set('session.client.address', null);
}
$remoteAddr = IpHelper::getIp();
// Check for client address
if (!empty($remoteAddr) && filter_var($remoteAddr, FILTER_VALIDATE_IP) !== false)
{
$ip = $this->session->get('session.client.address');
if ($ip === null)
{
$this->session->set('session.client.address', $remoteAddr);
}
elseif ($remoteAddr !== $ip)
{
throw new InvalidSessionException('Invalid client IP');
}
}
}
}
Then save that file back to your server and test with CloudFlare again and report back if you think this fixed your issue.
I try this solution but I have the same problem...
on the site you sent me? The first access of the site after applying this fix should error - thats normal because you have to stabilise your session to use the right IP address and it would have already stored the wrong one. Also delete all your cookies to remove any old session cookies.
Have you ensured that Behind Load Balancer is also enabled in Joomla Global Config. This will then log you out a further time as the Ips being used validate the sessions will be different, so its best to:
public $behind_loadbalancer = true;
in /configuration.php
It worked for me!!
Thanks PhilETaylor!
It worked for me!!
Awesome. Thanks for testing.
I'm sorry, on the first attempt this afternoon I forgot to activate the loadbalancer and therefore it didn't work.
I tried again and actually this solves the problem.
Thank you very much.
Marco
Awesome news - thanks
That seems to have done it for me as well. Two J4 sites side by side. Applied the fix to one and not the other. Big difference!
Thank you so much for all your help!
At the moment, this workaround is working for me.
Thank you for to take your time to investigate and bring us the needed help.
This is gonna be a rather long technical explanation / history lesson / proposed fix, so brace yourselves.
It all starts with how the Joomla session management works.
The session service is provided by the libraries/src/Service/Provider/Session.php
file.
The correct session service for the installation, web, administrator or cli (console) application is aliased in each application's app.php
file, e.g. the includes/app.php
file for the public site a.k.a. front–end application.
This is used in src/Service/Provider/Application.php
to inject the correct session object into the application object.
At this point the session object is there but the session is inactive; Joomla has not checked whether there is a session or whether this is valid.
If you dive into the Joomla\CMS\Session\Session
class which what all these sessions objects use you will see that it extends the Joomla! Framework's Joomla\Session\Session
class. In there you will see that the session is actually started, resumed or invalidated the first time we try to access its contents.
This happens very early in the Joomla application object initialisation in CMSApplication
itself when it calls doExecute
. This method implementation in all three web application objects (site, administrator and api) start by calling Factory::getUser()
.
If you follow that rabbit hole you will see that it immediately tries to load the user
key from the session. The get
method on the session calls the session's start
method which in turn calls the validate
method. If that method returns false the session is destroyed and restarted.
Now we get to the devil while lies in the (implementation) details.
Remember libraries/src/Service/Provider/Session.php
which sets up the sessions? Its buildSession
method adds the Joomla\Session\Validator\AddressValidator
validator to the validation stack. As @PhilETaylor pointed out, this uses $_SERVER['REMOTE_ADDR']
through the Input object:
$remoteAddr = $this->input->server->getString('REMOTE_ADDR', '');
Since this file belongs to the Joomla! Framework which is its own separate entity we can't possibly change it to tie it into Joomla's “Behind load balancer” configuration setting. At best we could have it go through the Joomla\Utilities\IPHelper
utility class (which is initialised with Joomla's ”Behind load balancer” setting in each application's framework.php
file) which is a bit problematic because it creates a hard dependency on that package which is not necessary outside of Joomla. That's what Phil did in joomla-framework/session#55
Even though it's merged, there's no guarantee this change would make into Joomla 4 since it requires a. the framework to publish a new version of the session package and b. Joomla 4 to update the dependency to joomla/session
.
Moreover, this approach does not address the elephant in the room: third party code could go either through the Joomla input object or directly through $_SERVER to get REMOTE_ADDR which still contains the wrong IP address. While this is only incidental to the problem at hand it can still cause a security issue.
It's easy to say that Joomla extensions MUST always go through IpHelper but this ignores some very simple facts: i. Joomla 3 is still supported until August 17th, 2023, doesn't have the IpHelper and most 3PDs still need to support it; ii. this was the way people were doing things in Joomla 3 so unless they have already bitten by an IP issue on J3 they won't know to change their code in Joomla 4; and iii. if a third party library is used it might actually use $_SERVER['REMOTE_ADDR'] with the developer being none the wiser. We can't plausibly tell 3PDs (or even core code!) to change third party code.
Speaking of which Joomla 4 includes two third party libraries which use REMOTE_ADDR already, maximebf/debugbar
and voku/portable-utf8
. LOL!
Neither does just removing the validators, as Phil did in #35509, address this devil in the implementation details. BTW, I fully agree with that PR because the IP address will change randomly. My 4G connection jumps IPs every few minutes or when I go between cell towers. My VDSL connection jumps IPs every one hour to dissuade people from hosting their own servers at home or at the office. But I digress.
The only two ways to deal with $_SERVER['REMOTE_ADDR'] are A. have the host configure their web server to trust an HTTP header claiming to have the correct client address or B. overwrite $_SERVER['REMOTE_ADDR'] when “Behind load balancer” is enabled.
The former is a pipe dream and a security nightmare rolled into one. Hosts will rightfully decline doing that since it's your problem, not theirs. It's also a security nightmare because you should only trust this kind of header when the actual REMOTE_ADDR belongs to a trusted source, something that Joomla doesn't do at all right now. It also cannot be fixed by third party code since the session initialisation which needs the correct IP address happens long before onAfterIntiialize
, the very first event third party code can attach itself to.
The latter is possible, with the asterisk of whether you actually trust the source of the IP address, and in fact Joomla was so kind as to copy the workaroundIPIssues
method from FOF into the IpHelper class... but never call it anywhere.
Considering that the ”Behind load balancer” option is only going to be turned on when the user _really trusts _ the source of the X-Forwarded-For HTTP header I would propose that we call IPHelper::workaroundIPIssues()
right after calling IpHelper::setAllowIpOverrides(true);
in the following files:
administrator/includes/framework.php
includes/framework.php
api/includes/framework.php
Remember, this fix is incidental to what we are discussing here and not enough on its own to fix the session problem. However, the existing proposed solutions are not enough either. Likewise, the “Behind load balancer” setting is necessary to fixing these issues but not enough on its own right. You need all of the above to deal with all issues which may arise from having a site behind a load balancer, a proxy (yes, this includes Apache behind NginX!) or a CDN.
It'd also be cool to have an exclusive allow list of IPs the user trusts to provide a valid X-Forwarded-For header as an optional security hardening tool (meaning: if the list is empty play dumb and accept it from everywhere, thank you very much) but that's another PR for another day, right?
the “Behind load balancer” setting
a misnamed setting if ever there was one.
@brianteeman I disagree. If we want to be pedantic it should be “Behind proxy” but this is confusing since we already have proxy settings. Trying to tell non–technical folks about the difference between a proxy for their outbound connections and a proxy in front of their site is far harder than calling this option “Behind load balancer” (the typical use case in server environments, I can attest to that based on our empirical data) and tell them that oh yes, this also applies if you are behind a CDN, a service that puts itself between your site and the Internet (e.g. Sucuri) or when your site is proxied through a (typically caching) proxy such as NginX, Varnish etc.
It should have been called "Phils alternative approach which was better than the JSST approach, which was just plain wrong, to a confirmed and reported security issue that allowed overwriting of several headers by hackers when a site was not behind a reverse proxy service such as a load balancer"
But that was too long.
IIRC The tooltip also specifically mentions such vendors like Sucuri and CloudFlare that provide this service and refers to it correctly as a "reverse proxy" as well as the generic user friendly term of "load balancer".
And back then the working on this feature highlighted another security issue in Joomla Framework where the - setAllowIpOverrides
was ALWAYS true by default!! joomla-framework/utilities#30 which was resolved.
Yes Phil thats exactly what I mean. Load Balancer or proxy would never spring to mind when using a service such as noc.org
I don’t think that "Use X-Fowarded-Fot HTTP header” or “Enable IP Workarounds” are particularly useful either. The former is technically what it does, the latter is what I call it in the software IpHelper was copied from. There is no good way to name this.
Can we now focus on the actual issues instead of beating a dead horse?
If you beat it hard enough it will come back to life
So, in Summary (users just want a solution to use Joomla 4 with CloudFlare, not the technical details!)
The fix already merged upstream joomla-framework/session#55 fixes the immediate issue for those that want to use CloudFlare, but equally it might never get merged to Joomla 4.x - many users confirm that works for them already.
A "better" fix which several agree on, is not to lock an IP address to a session, A solution for that has been proposed in #35509 and if merged will fix the CloudFlare specific issue instantly. The fix in 1 above, although nice to have, would not be needed for those user. For users having a CloudFlare specific issue today, they can quickly remove the lines referenced in #35509 and their Joomla 4 site will work without logging them out.
Additionally #35524 has been proposed, which overwrites REMOTE_ADDR if needed, to provide the broadest compatibility with 3PD, who dont take the care to understand these issues, and who rely on REMOTE_ADDR being the users IP always.. This should also be merged for the additional reasons stated in the PR.
In addressing these issues, An additional confirmed security has been found and escalted to the JSST, with proposed solution, for them to address in the next version.
Am I right? If so then this issue can be closed, as its been adequatly addressed in the PR's above to cover all aspects.
Please test the open PRs if you have the technical understanding, and CloudFlare (and or other proxy WAF services) to test with.
Delete the lines in libraries/src/Service/Provider/Session.php
that are highlighted in red on this page: https://github.com/joomla/joomla-cms/pull/35509/files
Enable "Behind Load Balancer"
in Joomla Global Config
You will probably want "Force SSL"
set to entire site if you are using CloudFlare to terminate SSL. There is no problem enabling this anyway.
Upgrade to the next version of Joomla 4 when released, it should all be fixed by then (Edit: It was not fixed in 4.0.3, fingers crossed for 4.0.4), with additional security fixes too.
Not sure if this is supposed to be fixed in 4.03, but it doesn't look like it to me. Sessions still get destroyed.
If I make the changes (again) from above, it works.
Neither #35509 or #35524 were merged in Joomla 4.0.3 and neither was joomla-framework/session#55 from the upstream library included - therefore I fully expect it to still be broken in Joomla 4.0.3.
If you are just here for a quick solution you can follow the instructions in #35244 (comment)
If you are competent and able, you can test the two open PR's and confirm they work, and mark a test result as successful on each PR, this will help them get merged faster if people test them.
Or @wilsonge can just make a decision to test and merge the changes quickly before the next version as the release lead for Joomla 4.
Thank you Phil your solution fix it for me aswell.
I installed Joomla 4.0.3 yesterday and this session issue drived me crazy. I am also under cloudflare.
I hope this fix is included on 4.0.4
Regards
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2021-09-24 07:02:06 |
Closed_By | ⇒ | HLeithner |
For those that would like to try - please apply these changes to your site and see if this fixes the issue for you (note: YOU DO STILL NEED the Behind LoadBalancer option enabled in Joomla Global Config)
If you dont know how to read a diff, try this, EDIT the file
libraries/vendor/joomla/session/src/Validator/AddressValidator.php
and replace the content of that file with this:
<?php /** * Part of the Joomla Framework Session Package * * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Session\Validator; use Joomla\Input\Input; use Joomla\Session\Exception\InvalidSessionException; use Joomla\Session\SessionInterface; use Joomla\Session\ValidatorInterface; use Joomla\Utilities\IpHelper; /** * Interface for validating a part of the session * * @since 2.0.0 */ class AddressValidator implements ValidatorInterface { /** * The session object. * * @var SessionInterface * @since 2.0.0 */ private $session; /** * Constructor * * @param Input $input The input object * @param SessionInterface $session DispatcherInterface for the session to use. * * @since 2.0.0 */ public function __construct(Input $input, SessionInterface $session) { $this->session = $session; } /** * Validates the session * * @param boolean $restart Flag if the session should be restarted * * @return void * * @since 2.0.0 * @throws InvalidSessionException */ public function validate(bool $restart = false): void { if ($restart) { $this->session->set('session.client.address', null); } $remoteAddr = IpHelper::getIp(); // Check for client address if (!empty($remoteAddr) && filter_var($remoteAddr, FILTER_VALIDATE_IP) !== false) { $ip = $this->session->get('session.client.address'); if ($ip === null) { $this->session->set('session.client.address', $remoteAddr); } elseif ($remoteAddr !== $ip) { throw new InvalidSessionException('Invalid client IP'); } } } }
Then save that file back to your server and test with CloudFlare again and report back if you think this fixed your issue.
WOW, this quick fixes really save the day. thanks again for posting.
This is not a full proof fix. This fix does not account for IPs that change on the user end.
Sent from my iPhone
On Oct 2, 2021, at 8:22 AM, Alex Wai @.***> wrote:
session = $session; } /** * Validates the session * * @param boolean $restart Flag if the session should be restarted * * @return void * * @SInCE 2.0.0 * @throws InvalidSessionException */ public function validate(bool $restart = false): void { if ($restart) { $this->session->set('session.client.address', null); } $remoteAddr = IpHelper::getIp(); // Check for client address if (!empty($remoteAddr) && filter_var($remoteAddr, FILTER_VALIDATE_IP) !== false) { $ip = $this->session->get('session.client.address'); if ($ip === null) { $this->session->set('session.client.address', $remoteAddr); } elseif ($remoteAddr !== $ip) { throw new InvalidSessionException('Invalid client IP'); } } } }
Please read the entire thread. Multiple cases are handled by multiple PRs. This issue is resolved.
Hello,
after update Joomla core to 4.0.3 version this problem occurred again.
If I change the code again it works, otherwise it doesn't.
Is it a change that does not happen by updating the Joomla core to next version (from 4.02 to 4.0.3)?
I must do it manually after each update?
Best regards
Marco
See my comment #35244 (comment)
Until the maintainers merge and release Joomla 4.0.4 this will remain an issue.
@PhilETaylor As far as I can see the two Pull Requests which fix this problem have been merged after 4.0.3 was released. As far as I know 4.0.4 will be released in the next couple of weeks, or at least that was the impression I was left with discussing the timeframe for a different issue's resolution.
The only PR not yet merged is an incidental side–effect I found nearly a month ago when trawling through the code for everything that uses the user's IP. Neither is critical. One's used for debugging (I'd wager a live site isn't a very good candidate for that!) and the other one is in an optional feature not used in the core code. It may still cause some WTF moments but we can live with those unlikely edge cases for a couple more months — unless the release leads magically have spare time to look at a low priority good–to–have feature, something which has the same chance as airborne pork or snow in July in the Northern Hemisphere.
So, based on what I see, in a couple of weeks we will finally be able to use Joomla 4 with CloudFlare and other similar solutions.
Correct. I was replying to Marco who said that they had upgraded and that broke everything again. Of course that was perfectly expected because the changes were merged after the last release. Like you say, once version 4.0.4 is released this should no longer be an issue.
Ah, OK. I misunderstood your reply as saying the changes are not yet merged. I was actually tracking these because I need Joomla 4 to work with CloudFlare for my sites and knew this wasn't the case, hence my reply. All good! I need coffee, is all.
Is it fixed in J 4.0.4?
As far as i can see the commit regarding the Joomla\Session\Validator\AddressValidator
is not included.
But the change in Joomla\CMS\Service\Provider\Session
is there
The change in Joomla\CMS\Service\Provider\Session is the fix being looked in the specific matter for Cloudflare for as the session will no longer check the IP for validation.
Sent from my iPhone
On Oct 26, 2021, at 5:16 AM, Sakis Terzis @.***> wrote:
Has somebody checked if it is fixed in J 4.0.4?
As far as i can see the commit regarding the Joomla\Session\Validator\AddressValidator is not included.
But the change in Joomla\CMS\Service\Provider\Session is there
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub#35244 (comment), or unsubscribehttps://github.com/notifications/unsubscribe-auth/AECIKFTCRUU6DNANMLRHCWLUIZ5XRANCNFSM5CPHRBPA.
Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
I investigate this problem earlier and probably it's happen because CSRF token is reset.
In my test case it was happen on free or cheaper hosting providers, like infinityfree.
On little more expensive hosting providers (1USD for month) it will not happen. Maybe it's special settings on hosting provider.
On both test cases I used cloudflare. And in 3.x problem not appear.
On site settings session time is 60 minutes and I tried to use file system storage and database to store session.