TryGhost / Ghost

Independent technology for modern publishing, memberships, subscriptions and newsletters.
https://ghost.org
MIT License
47.59k stars 10.38k forks source link

Express:sess cookie is blocked by Chrome #12173

Closed Barbaro closed 3 years ago

Barbaro commented 4 years ago

Hi everyone.

Issue Summary

When your site is private, after entering the right password, it tries to create a "express:sess" cookie. The problem is that the cookie has samesite=none property defined. So, Chrome is blocking it if you're not using HTTPS on your blog, wich is my case :(

The error in chrome console : A cookie associated with a resource at http://****/ was set with SameSite=None but without Secure. It has been blocked, as Chrome now only delivers cookies marked SameSite=None if they are also marked Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5633521622188032.

To Reproduce

  1. Make your site private
  2. Enter the right password
  3. You are back on the password page, with an error in the console.

Technical details:

Thanks for your answers.

imox2 commented 4 years ago

Cookies are used in either Cross-Site or Same-Site Context

Today, if a cookie is only intended to be accessed in a first party context, the developer has the option to apply one of two settings (SameSite=Lax or SameSite=Strict) to prevent external access. I think this is our case. If it is then then maybe we can change SameSite='None' to one of these

Chrome made the following changes in chrome 80 from Feb 2020:

  1. To safeguard more websites and their users, the new secure-by-default model assumes all cookies should be protected from external access unless otherwise specified.
  2. Developers must use a new cookie setting, SameSite=None, to designate cookies for cross-site access.
  3. When the SameSite=None attribute is present, an additional Secure attribute must be used so cross-site cookies can only be accessed over HTTPS connections.

Info from : chromium blog

mattaebersold commented 4 years ago

I'm having the same issue here, though we're using https

Notes:

Any update on this, how to fix, etc, would be great

antucg commented 3 years ago

I have been facing this problem and the only solution I have found is to modify the middleware that is setting the cookie. I know it is not the best solution but it is the only one that worked for me.

I have deployed the blog with Docker so the path may change depending on your solution, the file to modify is this: core/frontend/apps/private-blogging/lib/middleware.js. If running in Docker it can be found under: /var/lib/ghost/current/core/frontend/apps/private-blogging/lib/middleware.js.

The advantage with Docker is that I can mount my modified version into that location directly. That way if that file is changed in the future, I can remove this mounting point and use the original file instead.

The solution is in the line 48, the code should be something like this:

return session({
  maxAge: constants.ONE_MONTH_MS,
  signed: false,
  sameSite: "none",
})(req, res, next);

I have commented out sameSite: "none", so it will use the default value, which is Lax if I am not wrong. I guess once my site is fully public I will remove this change so it will use the original file again.

Regards.

iampawan commented 3 years ago

Facing the same issue. Any help?

jeffreycunn commented 3 years ago

I am also facing the same or similar issue.

My setup is the Bitnami Ghost Stack for Google Cloud VM behind a https load balancer that provides a google managed SSL cert. Cloud armor is activated. Whenever I activate the "Make this site private" I am unable to access the site (error 502). When I access the site with direct IP rather than going through the load balancer, I am able to get to the site, but cannot login. After entering the password for either the overall site or example.com/ghost/ I am redirected back to the site.

I was able to temp fix the issue by modifying the URL in /opt/bitnami/apps/ghost/htdocs/config.production.json to the direct IP instead of the domain I am mapping to the site. I may try @antucg suggestion next until there is a more clear fix. I am not going live with the site yet, so I have a little time, but would like to be able to put the site behind a password .

Thanks! Jeff

ErisDS commented 3 years ago

This has stopped working for some people due to a change in Chrome: https://web.dev/samesite-cookies-explained/#samesitenone-must-be-secure as mentioned by @imox2.

The short version is that for the cookie to work in Chrome, sites in private mode must be secure - i.e. must be served over https.

This is a future-facing change from Chrome, as the web moves towards being https by default.

Note: changing the value of SameSite is not a viable fix, as this is required for serving Ghost admin on a different domain to the frontend, which is an important and commonly used security feature.

We're going to close this issue as a "won't fix" as there's no simple solution, and it makes sense to limit private mode to being secure.

cmsax commented 3 years ago

I'm facing this issue too. I use docker and nginx to serve a ghost blog, with a general ssl certificate. Following is my nginx config snippet:

# ghost 
 server {
     listen 443 ssl http2;
     server_name [TYPE YOUR SERVER NAME HERE];

     location / { 
         proxy_pass http://localhost:2368;
         proxy_set_header Host $http_host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
     }   
 }

It might help.

ErisDS commented 3 years ago

I’m going to lock this issue, as I’ve provided an extensive explanation above as to how this is is a configuration issue. If anyone needs help debugging individual configurations, then https://forum.ghost.org is the right place for that.