Django Cookie Detection Fails Though Cookie Hasn't Expired - python

I have a cookie on the client browser to store a hash value. I've extended the cookie lifetime using this
response.set_cookie('kmliCookie', randomHash, settings.COOKIE_LIFETIME)
and firefox shows that this cookie expired next month.
When I refresh the page, django detects the cookie even if I close the browser and come back the cookie is detected but after a system restart (may be due to IP change) the cookie is not detected.
Its not even there in the request object. But firefox still has the cookie and it's not expired.
I use this code to detect the cookie
if request.COOKIES.get('kmliCookie'):
message = "valid"
else:
message = "invalid"
it results in invalid (only after system restart or ip change).
I used this to check the request object.
render(request, 'index.html', {'request':request.COOKIE})
and request object didn't have kmliCookie.
What am i doing wrong here?

Related

Python/Flask cookies not being deleted in Safari

I am having an issue where my users cannot log out in Safari, unless they close the tab entirely. Additionally, this DOES work in Safari if Private Mode is on. Safari also does not persist the session/cookie between tabs.
I am setting a cookie that holds some session data (user ID, name, etc) and have a log out button that calls the same Python backend that sets the initial cookie with that data.
Set:
resp = make_response(redirect('https://mydomain.c0m'))
resp.set_cookie('my-account', json.dumps(user_data), domain='.mydomain.c0m')
return resp
Remove:
resp = make_response(redirect('https://mydomain.c0m'))
resp.delete_cookie('my-account', domain='.mydomain.c0m')
return resp
This works perfectly in a Chromium or Firefox browser and if Safari is in private mode. My /login endpoint is called- the cookie is created. The /logout endpoint is called, the cookie is gone.
In Safari, I cannot even see the cookie in the local storage tab. Logging in works and returns the user_data as expected. Logging out does not work. It calls the Python backend, returns 200, but nothing has effectively changed until I kill the entire browser.
This is the cookie, as viewed through Edge (Chromium):
Safari:
Created, then deleted the cookie by calling the /login and /logout endpoint in Safari. In the same tab, the user session cookie keeps existing. I have access to the user profile and can use the data in the cookie to modify the profile. The "logout" button face also does not change (this changes depending on whether or not the cookie is present and has data)
The session does not appear to be shared between tabs. Logging into one open tab does not log in the other. An established session in one tab will not persist in a new tab.
Firefox:
Created, then deleted the cookie by calling the /login and /logout endpoint in Firefox. In the same tab, the session is properly started or ended. I no longer haver access to the user profile and the "logout" button face changes to "login". The session state being established or ended is shared between tabs.
Chromium:
Created, then deleted the cookie by calling the /login and /logout endpoint in Edge. In the same tab, the session is properly started or ended. I no longer haver access to the user profile and the "logout" button face changes to "login". The session state being established or ended is shared between tabs.

Flask Blueprint Putting something on session

I was trying to put
session['logged_in'] = True
in the session, but in another blueprint it doesn't persist... Why is that?
Is there any better way to keep something in the session?
Extended:
I have a blueprint giving a form to login. When done and submitted, it will set a session key like above. Then it redirects via
return redirect(url_for('admin.index'))
to admin page where If I call the key via
session.get('logged_in')
I get "None" Instead of the True or False one.
I think I understand your confusion now~
Your flask session won't store anything on the server.
the 'session' dict is filled by the cookies from the client request.
Again. that is:
client make login request to server, and got a [login success] response as well as a [cookies] which contains the !!!sessionINFO!!! you think are stored on the server side.
Next time, you must send the whole cookies to the server again, then your session in the server may have data.
Browser will do this for you.
If you use a local client, say python requests library. Then be sure you are making requests with session (for requests-lib, it's requests.Session())
------------------OLD-------------------------------------
Though not an expert, but the case you described should not have happened.
The session is cookies data encrypted with a secret, if you have gone through the document mentioned by Beqa.
Just set
app.secret = '........'
And use session as a dict.
just FYI,
client request---->server (encrypt your_data 'logged_in' and client_relating_data 'maybe: ip, host or etc.', and put the encrypted info in cookies 'session=....') ------> client (get response with cookies)
client request again -----> server (decrypt the cookie 'session=...' with your secret), find the 'logged_in' data and know you are logged in.)
the cookies is something like below.
So, I'm not sure what's actually your trouble when using session, and put some basic information here. Just hope it helps in case.

Django - sessionid cookie - Is this a security failure?

In order to see this possible error you need to open two browsers and some plug-in to get/set cookies.
If you create a new project in django 1.7 and access to the admin site (/admin), and login succesfuly in the first broser and get the sessionid and csrftoken cookies and set them into the second browser login page and set a random user and password, you obtain a CSRF error and if you go back in the browser you are logged in.
how can avoid this?
I suppose, you can obtain same result just by copying sessionid cookie to another browser and navigating /admin. You don't need csrftoken to reproduce this issue. It's called sessionid stealing and all frameworks I know are vulnerable to this type of attack.
To avoid it, set SESSION_COOKIE_SECURE = True (default False) to protect your sessionid cookie from man-in-the-middle attacks. You will also need to install ssl certificate on your production server. Then configure it to redirect all http:// requests to https://. S in https stands for secure, this means all traffic between client and server is encrypted, and no one between client and server (client's ISP, server's hosting provider, proxies, etc) can read any data is sent. Including session cookie value.
And use SESSION_COOKIE_HTTPONLY = True (default) to protect session cookie from stealing via XSS. HTTPONLY means that this cookie will be sent with each http request, but won't be accessible from client's browser via javascript. So if some malware javascript managed to run in client browser, it will not have access to session cookie anyways.
Good tutorial on configuring secure django server can be found here: https://security.stackexchange.com/a/8970

How to check browser cookies support with Pyramid

I would like to know, when is the right moment and how to check the browser cookies support.
I understand I have to check the next request and for instance, with beaker, looking for the session key _creation_time or request.headers['Cookie']... and raise an exception if not found but I don't want to do that or something similar for every request. Some parts of my application don't require cookies, like the home page or info, faq page...
When a user logs out, the session gets deleted or invalidated and I used to redirect to the home view, if I check the session key at that moment, I'll not find it but it doesn't mean there is this issue.
An example I used at the beginning of login view:
try: request.headers['Cookie']
except KeyError:
return HTTPFound(location=request.route_url('home'))
Please also note that if I try to print an error message using request.session.flash(msg, 'error') or use the snippet again at the beginning of the home view and render a message with the template using a control return variable, after logout it will be erroneous displayed.
I am looking for the most elegant way to resolve issue...maybe subscribe to a event?...write down a function to call in some interested view?
There are a few things that could the cause of your problems.
Before I continue... FYI Pyramid uses WebOb to handle request and response objects
WebOb Overview
WebOb Class Documentation
Scenario 1
If you call set_cookie under Pyramid , and then do a redirect, the set_cookie will not be sent. This is because redirects create a new response object.
There are a few ways around this:
The most straightforward is to just copy response headers into the cookie when you raise/return a redirect
return HTTPfound( "/path/to/redirect", headers=[ (k,v) for (k,v)\
in self.request.response.headers.iteritems() if k == 'Set-Cookie'] )
OR
resp = HTTPFound(location='/path/to/redirect')
return self.request.response.merge_cookies(resp)
I should also note that MOST browsers accept cookies on redirects, however Safari does not.
another way is to use pyramid's hooks to convert cookies behind the scenes. i wrote subscribers that automate this. they're on pypi and github. https://github.com/jvanasco/pyramid_subscribers_cookiexfer
Scenario 2
There are two ways of handling sessions in Pyramid. Pyramid has its own session library, and then there is Beaker, which handled sessions for Pylons and has Pyramid support that many people use. I can't speak of pyramid.session, but Beaker has two modes to kill the session:
delete()
Delete the cookie, and clear the session
invalidate()
Clear the contents and start a new session
If you call invalidate(), the Beaker session cookie stays the same and all the session data is cleared -- so you can start storing new data into an empty session object.
If you call delete(), the cookie gets killed as does the session data. If you put new information into the session, IIRC, it will go into a new sessionid / cookie . However, as I noted in the first part above, set_cookie will get called but then thrown out during the redirect. So if you delete() the session and then don't migrate the set_cookie headers... the client will never receive a session identifier.
Some example behaviors of cookies under pyramid
Behavior of redirect
User visits site and is given cookie: SessionId=1
User clicks login
App saves login status to session "1"
App calls set_cookie with "LoggedIn=1"
App calls redirect to /home
Redirect sent, no cookies
User lands on /home
App only sees cookie for "SessionId=1"
Behavior of delete with redirect:
User clicks logout
App calls 'delete()' on session, killing the datastore and placing a set_cookie in request.response to expire the old cookie. if a new sessionid is created, that is sent as well.
If app renders a response, then client receives cookies
If app redirects, client does not receive headers to expire the cookie or set up a new one
Behavior of invalidate with redirect:
User clicks logout
App calls 'invalidate()' on session, killing the datastore
App sets a custom "loggedout=0" cookie
If app renders a response, then client receives cookies
If app redirects:
Client does not receive "loggedout=0" header
Client still has the old session cookie, but it was invalidated/purged on the backend, so they are effectively locked out.
side note: I personally don't like using the request.headers interface -- which handles all headers -- to get at cookies. I've had better luck with request.cookies -- which returns a dictionary of cookies.

delay in finding facebook cookie using JS + Python

Using a mix of GAE, Python and JS I have successfully made a application connecting to facebooks API. Only one snag: In my app - the first thing i check is if a facebook cookie exists:
cookie = facebook.get_user_from_cookie(self.request.cookies,
FACEBOOK_APP_ID,
FACEBOOK_APP_SECRET)
if cookie:
{render index.html}
else:
{render login.html}
In my login-handler i again check for a cookie (same codestructure) to avoid having people who does have a cookie accessing this page. This works as designed.
Only problem is that when a cookie does exist, there seem to be some delay in detecting this. So, the log goes:
cookie not found in index-handler, redirecting to login-handler
login-handler draws login-html
cookie found in login-handler, redirecting to index-handler
index-handler draws index-html
This is clearly visible to end-user, the loginscreen draws and then, a second or so later, the correct indexscreen is drawn.
What can be the cause of this delay? I'm wondering if its caused if the cookie is being transferred to the server? If so, how to code around this?
Cookie fbsr_<application_id> will be set only after user is authenticated on Facebook, redirected back to your application and Javascript API method FB.init() is executed with cookie: true.
FB.init({
appId : '<application_id>',
status : true,
cookie : true,
//...
In other words, cookie is not set immediately after user is redirected back to your application.

Categories