bungle / lua-resty-session

Session library for OpenResty – flexible and secure
BSD 2-Clause "Simplified" License
320 stars 111 forks source link

Sometimes decryption fails #7

Closed vladimir-smirnov-sociomantic closed 9 years ago

vladimir-smirnov-sociomantic commented 9 years ago

It seems for me, that sometimes encryption fails.

The best way to reproduce is to try access Nagios and use nginx's oauth plugin: https://github.com/vladimir-smirnov-sociomantic/nginx-oauth-on-dotcloud (mine fork, because not all changes are merged for now).

With debug log I've found that sometimes I receive data from redis/cookies, but they fail to decrypt

bungle commented 9 years ago

Do you also experience this with client side session storage as implemented in v. 1.5 in my repository? Or is the problem only in your implementation of it? If you also experience a problem in my v. 1.5, then let's keep this open. Otherwise let's discuss this on that pull-request page: https://github.com/bungle/lua-resty-session/pull/6

Regards Aapo

vladimir-smirnov-sociomantic commented 9 years ago

I'll check this. I've defenitely got this with 1.3, and I think I've got same problems with 1.4, but I'm not sure. I'll check this tomorrow.

bungle commented 9 years ago

Okay, thanks. Also when you do that check try it with all the extra checks disabled (false) (that is session.check.ssi, session.check.ua, session.check.scheme, session.check.addr).

Are you using that iframe with the same session? Are they both pointing to same session.cookie.domain and is the session.cookie.path set to / (which is the default). Also are you using same protocol for both? Also check all the other settings that they are same if you are using same session for both. Also check that you are not experiencing this: http://serverfault.com/questions/318047/cookie-not-send-in-ie-when-used-in-an-iframe-from-another-domain

vladimir-smirnov-sociomantic commented 9 years ago

Ok, I'll try to do that with what the code will be "current latest stabe" tomorrow morning (CET)

It's in the same session (most of the time). Protocol is same for both. Domain is same, it's just something like 40 resources (gifs, jpg, html, css, js) per request. And for all of them I'm checking cookie (to have github's access_token). And sometimes it just fails to decrypt one.

bungle commented 9 years ago

Yes, it is possible that there is a race condition. Do you have frame(s) on a landing page?

bungle commented 9 years ago

You could also try (these are just plain pseudo-code examples): https://github.com/openresty/lua-resty-lock

e.g.

Nginx

lua_shared_dict session_locks 100k;

Lua

-- no error handling implemented here
local lock = require "resty.lock":new("session_locks")
-- let's just in this example always lock with the same key
-- just to figure out if it is indeed a race condition
-- (we should probably only lock on session.id, but it is harder to implement)
lock:lock("session.lock")
    local session = require "resty.session".start()
    -- do something with the session
lock:unlock()

Locking on session.id we could have something like this:

-- again, no error handling code implemented here
local lock, session = require "resty.lock":new("session_locks")
lock:lock("session.start")
    session = require "resty.session".start()
lock:unlock()
-- if you ready to write something to session
lock:lock(session.id)
    -- do something with the session
    -- ...
    -- and finally save it
    session:save()
lock:unlock()

PHP does something similar: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

I think that we might need to implement locking in the session library as well (I'm not sure though if this is needed for client side sessions as well - probably only in that case when you want to insert a few iframes on a page that is served by some other site; I mean that with client side cookie storage you should get the cookie with the first page load (that contains a links to other resources), then browser should automatically add that cookie to furher requests - you should close the session only with full POST to some other page (and you shouldn't modify session data on subrequests, if you do there is a change that simultaneous subrequests are overwriting each other - e.g. a counter - then you need a lock as well)).

vladimir-smirnov-sociomantic commented 9 years ago

Yes, there are several frames on a page.

I'll try resty-lock, thanks!

ghost commented 4 years ago

I think that we might need to implement locking in the session library as well (I'm not sure though if this is needed for client side sessions as well - probably only in that case when you want to insert a few iframes on a page that is served by some other site[...]).

@bungle Please implement a function to use a lock, otherwise race conditions are hard to debug / find. -Turning off locks by default would be the best from my point of view.