Wednesday, January 10, 2018

logout not working, caching on nginx, how to allow logout?

Leave a Comment

I have everything cached, if I logged into my account, you will not be able to log out any more) how do you get out when you quit? i need to know how to delete cookies and session! when i'll logout!

P.S. if i'll disable caching on nginx level, everything works fine, problem in nginx

nginx conf

    gzip on;     gzip_disable "msie6";      gzip_vary on;     gzip_proxied any;     gzip_comp_level 6;     gzip_buffers 16 8k;     gzip_http_version 1.1;     gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;      proxy_connect_timeout 5;     proxy_send_timeout 10;     proxy_read_timeout 10;     proxy_buffering on;     proxy_buffer_size 16k;     proxy_buffers 24 16k;     proxy_busy_buffers_size 64k;     proxy_temp_file_write_size 64k;      proxy_temp_path /tmp/nginx/proxy_temp;     add_header X-Cache-Status $upstream_cache_status;     proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=first_zone:100m;     proxy_cache one;     proxy_cache_valid any 30d;     proxy_cache_key $scheme$proxy_host$request_uri$cookie_US; 

server conf

upstream some site {   server unix:/webapps/some/run/gunicorn.sock fail_timeout=0; }  server {     listen   80;     server_name server name;     expires 7d;     client_max_body_size 4G;      access_log /webapps/some/logs/nginx-access.log;     error_log /webapps/some/logs/nginx-error.log;     error_log /webapps/some/logs/nginx-crit-error.log crit;     error_log /webapps/some/logs/nginx-debug.log debug;      location /static/ {         alias   /webapps/some/static/;     }      location /media/ {         alias   /webapps/some/media/;     }     location ~* ^(?!/media).*.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {         root root_path;         expires 7d;         add_header Pragma public;         add_header Cache-Control "public, must-revalidate, proxy-revalidate";         access_log off;     }         location ~* ^(?!/static).*.(?:css|js|html)$ {         root root_path;         expires 7d;         add_header Pragma public;         add_header Cache-Control "public, must-revalidate, proxy-revalidate";         access_log off;     }           location / {         proxy_set_header X-Real-IP $remote_addr;         proxy_cache one;         proxy_cache_min_uses 1;         proxy_cache_use_stale error timeout;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;         # proxy_set_header X-Forwarded-Proto https;         proxy_set_header Host $http_host;         proxy_redirect off;         if (!-f $request_filename) {             proxy_pass http://some;             break;         }     }     error_page 404 /404.html;     location = /error_404.html {         root /webapps/some/src/templates;     }      error_page  500 502 503 504 /500.html;     location = /error_500.html {         root /webapps/some/src/templates;     } } 

2 Answers

Answers 1

Instead of logging out with a GET request, change your logout view to accept a form POST.

POST requests should not be cached.

This has the added security benefit of preventing users from being logged out with iframes or malicious links (ie: https://example.com/logout/, assuming you have not disabled django's CSRF protection).

Answers 2

You have the following question:

i need to know how to delete cookies and session! when i'll logout!

With the following code:

proxy_cache_key $scheme$proxy_host$request_uri$cookie_US; 

We first have to know what's in $cookie_US?

  • If it's simply the name of the login, then you need to realise that anyone who knows the name of the login, and sets their own cookie as such, and knows the complete URL of a hidden resource that such user (and only such user) has access to, and which has been accessed recently (thus freshly cached), can now gain ‘unauthorised’ access to the given resource, since it'll be served straight from cache, and likely without any sort of re-validation.

Basically, for caching user-specific content, you have to make sure that you set http://nginx.org/r/proxy_cache_key to represent an actually secret non-guessable value, which could then be cleared on the user's end to logout. Subsequently, if the user does logout, then your cache is still subject to the replay attacks by anyone who somehow still posesses such secret value, but it'd usually be minimised by a short expiration time of the cache, plus, the secret is still supposed to stay a secret even after logout.

And clearing the session is as easy as simply re-setting the variable to something that wouldn't be giving the access to the user, e.g., you can even implement the whole logout thing entirely within nginx, too:

proxy_cache_key $scheme$proxy_host$request_uri$cookie_US; location /logout {     add_header Set-Cookie "US=empty; Expires=Tue, 19-Jan-2038 03:14:07 GMT; Path=/";     return 200 "You've been logged out!"; } 

P.S. Note that above code technically opens you up to XSS attacks — any other page can simply embed an iframe with /logout on your site, and your users would be logged out. Ideally, you might want to use a confirmation of logout, or check $http_referer to ensure the link is clicked from your own site.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment