Jump to content

Leaked session data on nginx server


sodesign
 Share

Recommended Posts

Hello,

I manage a client website which use PW and Padloper for ecommerce.

We recently had an issue where customers were seeing other customers' baskets and prefilled form data on the checkout form.
From what I saw, the data was not users who had accounts, just data which was held in their sessions.

I think I have narrowed this down to being caused by nginx fast-cgi caching, but I do not know enough about how this works to be certain.

I have a couple of questions:

• Can fast-cgi cached cause session data to be shared, leaked or incorrectly assigned?
• Can fast-cgi cache provide authentication to unauthorised users?

I'm reasonably confident that the whole shop cart and checkout bypassed the cache, so is it possible that somebody could 'swap' sessions on a diffetent part of the site which shouldn't have been cached?

I don't have a great deal of knowlegde of how sessions, caching and cookies work and fit together, so if it's likely that the fastcgi-cache isn't the problem, can anyone point me in the direction of what might be?

 

Link to comment
Share on other sites

  • 3 weeks later...

Hi @sodesign ,  interesting, did your issue is fixed ? if yes, how ? thanks;

And to answer the two questions :  Yes, but it should only do that if you tell NGINX to do it.

 

About the issue, and based on your post, it look like a cache issue where cookies has been cached.

The official statement say that by default, NGINX respects the Cache-Control headers from origin servers. It does not cache responses with Cache-Control set to Private, No-Cache, or No-Store or with Set-Cookie in the response header. This is the current behavior; 

I will add that before the version 0.8.44, the header was stripped then the request cached. 

 

All that to say that theses parameters can be overridden, and you should show us your NGINX config file before we go further.

 

 

  • Like 2
Link to comment
Share on other sites

Thanks for your reply @flydev 👊🏻

I have looked through our nginx config, and I can see the lines

fastcgi_ignore_headers Cache-Control Set-Cookie Expires;
fastcgi_pass_header Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_cache OPS-FASTCGI;
fastcgi_cache_valid 240m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;

The $no_cache param is set based on the request uri, and I did notice one 'private' url had been missed from the exclusions at the time of the issue.

This really isn't my area of expertise, and we set up the config some time ago, inspired by Trellis (in wordpress land). I noticed someone questioned them about the inclusion of the fastcgi_pass_header Set-Cookie property (https://discourse.roots.io/t/nginx-caching-configuration-in-trellis/7056)

Would removing fastcgi_pass_header Set-Cookie be a good idea? Is there any reason this would need to be passed?

Link to comment
Share on other sites

  • 2 years later...

Re leaking: I believe nginx uses the request url as the cache key and that only GET requests are cached (not sure about OPTIONS or HEAD). So if you have caching enabled and a logged in user, Wilma, requests /processwire/user to see their profile, the next user, logged in or not, will also see Wilma's record. Typically it's ok to disable caching for logged in users, and/or you can also disable caching on certain urls (or patterns of url) that you know to be sensitive.

Don't know if this is helpful or not, but here's the sort of thing I use for Drupal.

map $http_cookie $session_cookie_set {
    default 0;
    ~SESS 1; # PHP session cookie
}
## Identify ajax requests so we can choose to not cache them
map $uri $is_drupal_ajax_request {
    default 0;                                              
    /system/ajax 1;                            
}

# ... then in your server block ...
fastcgi_cache_bypass $session_cookie_set $arg_nocache $is_drupal_ajax_request;
fastcgi_no_cache     $session_cookie_set $arg_nocache $is_drupal_ajax_request;

What this does is:

  1. set up a variable `$session_cookie_set` which will be 1 if there is a PHP Session cookie in the request
  2. Set up a variable `$is_drupal_ajax_request` if the path is `/system/ajax` (a special path for drupal, but you can add your own var name and url patterns in here for your own use/processwire uses).
  3. Tells nginx to bypass and not cache results if any of these, or the `nocache` URL query variable is set.

I'm keen to use pw with nginx because .htaccess is ineffficient (from what I've read) and because I get on better with the reasoning of nginx's config; it seems to have fewer quirks than apache!

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...