When using suas in GAE and setting the flash_msg, for some reason the cookie does not expire. The symptom is that no mater how many times I refresh the page the flash message is always there. When I debugged with chrome I can see that the expiration the flash_msg cookies was set to session. Even more troubling I found that all cookies expiry are set to session. Any idea? The only change I made to the SUAS code was removing the error raising in
def __ParseString(self, str, patt=Cookie._CookiePattern):
Also note that the flash_msg cookie has a domain other then "/".
Update:
All the variables being session-ed are because they were meant to. SUAS has a persist variable that sets if the cookies will be session cookies or persist. As a work around for the flash messages I use the jQuery plug in for cookies and just delete the guys after I display them.
Those cookies do not expire on page load. They expire when the browser closes. What you need to do is at every page load, if flash is in session, display it and then force remove it from the session (on the server side).
Related
In my Django project, until recently I had left the settings SESSION_COOKIE_DOMAIN and CSRF_COOKIE_DOMAIN unset. Recently I changed them to .mydomain.com and since then I have been seeing sporadic CSRF failures on AJAX requests for certain users. The failure manifests as a 403 with CSRF token missing or incorrect. appearing in the logs.
Asking users to clear cookies seems to resolve the issue, but I'm wondering how the settings change could have caused this and why it only seems to be happening for some users and not others.
Wondering if there is a way to resolve these issues without asking my users to clear cookies.
The cookie with the new SESSION_COOKIE_DOMAIN is sent as a new cookie and does not replace the old one. So the browser will send both to your server. AFAICT, it sends them in arbitrary order.
That means that you're setting a cookie for .mydomain.com, but receiving either the cookie you just set for .mydomain.com, or a stale cookie for whatever.mydomain.com was implicitly set originally (because django will only pick one, most likely the last it sees). Which one you get depends on the browser, possibly on some particulars of how the client computer stores them, and possibly even on how django reads the headers. This is why the failures are inconsistent: it randomly works for some clients and fails for others.
Edit: You could delete the stale cookie from the server, if you know the original cookie's properties. Probably the best way is to set a custom Set-Cookie header with the domain and other properties set, and expiration date in the past. You could do that e.g. from the 403 page handler.
(see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie and Correct way to delete cookies server-side )
I'm learning flask and want to understand how sessions work.
Apparently the server stores a signed cookie on the client browser.
I have done this process using
sessions['mycookie'] = 'mycookievalue'
But I'm unable to find the cookie on the browser. I normally list cookies on the browser using chrome developer tools and running the command:
document.cookie
This works when I set a cookie but nothing comes up when I set it through sessions.
The Flask session cookie has the httponly flag set, making it invisible from JavaScript.
It is otherwise a normal, regular cookie so it is still stored in the browser cookie store; you should still be able to see it in your browser's developer tools.
You can set the SESSION_COOKIE_HTTPONLY option to False if you want to be able to access the cookie value from JavaScript code. From the Builtin Configuration Values section:
SESSION_COOKIE_HTTPONLY
controls if the cookie should be set with the httponly flag. Defaults to True.
The cookie contains all your session data, serialised using JSON (with tagging support for a wider range of Python types), together with a cryptographic signature that makes sure the data can't be tampered with securely.
If you disable the httponly protection, any JS code could still decode and read all your session data. Even if it can't change those values, that could still be very interesting to malicious code. Imagine a XSS bug in your site being made worse because the JS code could just read a CSRF token used to protect a web form straight from the session.
I am finding this question 3 years and 8 months later because I have an interest in the event it is modified or spoofed, to ensure my backend is able to tell the difference.
Using chrome, use F12, select Application tab, underneath Storage go to Cookies. Under cookies you'll find the webpage, select it and the right side will populate and assuming you have done something to create your session cookie, it will be there. You will notice that the value is encrypted.
Picture showing the location of session cookie
sessions are meant for server use only. That is why it is hidden and encrypted for the client.
If you want to set a cookie which can be used by client/browser. You can just set a normal cookie instead of a secure cookie (like session).
You can set cookies by modifying response.
def home_page():
resp = make_response(...)
resp.set_cookie('my_cookie', 'cookie_value')
return resp
document.cookie on browser will give you mycookie=cookie_value
I'm currently developing a site with Python + Django and making the login I started using the request.session[""] variables for the session the user was currently in, and i recently realized that when i do that it generates a cookie with the "sessionid" in it with a value every time the user logs in, something like this "c1cab412bc71e4xxxx1743344b3edbcc" and if I take that string and paste it in the cookie on other computer in other network and everything, i can have acces to the session without login in.
So what i'm asking here actually is if anyone can give me any tips of how can i add some security on my system or if i'm doing something wrong setting session variables?
Can anyone give me any suggestions please?
Sadly, there is no best way you can prevent this from what I know but you can send the owner of an account an email and set some type of 2fa.
There are a couple of things that can do to help improve the security on session cookies.
You can force a session to expire as soon as the user closes their browser.
In your settings.py file add:
SESSION_EXPIRE_AT_BROWSER_CLOSE=True
You can manually set the number of seconds until a session expires
Using the first argument(request) of any view:
request.session.set_expiry(value) # number of seconds or timedelta object
To address your specific issue, please consider that what you are describing is actually one of the primary features of session security cookies. They are convenience tools that enable users to use the secured parts of site without having to re-authenticate with every page request. Even the cross browser aspect of it is a feature since many apps and browsers provide a sync feature that allows you to share cookies and sessions datas with your mobile and other devices and other web browsers.
If you still feel that this is too significant of a security risk, then probably the safest approach would be to remove the SessionMiddleware
from MIDDLEWARE and django.contrib.sessions both in your settings.py
I have and API service that make this:
session[parent].pop(child)
But, when I call this service more than one time and at the same time in Browser, this seems too fast for Flask (or Python, or I don't know). Just one 'child' is removed. I tried to use
del session[parent][child]
but the problem was the same. I can get a list of values in my API Service to resolve that, but, I want to understand why this is happening.
I don't know if it is a Flask problem, a Python problem, a 'Web Stuff' problem...
It's a 'Web Stuff' problem.
What happens is that the browser stores the last version it received. But if it receives responses out of order, or you abort a request before it is completed, the browser won't be storing that version.
Flask stores the data for session entirely in a cookie. There is nothing stored on the server side other than the server-side secret used to encrypt and decrypt the contents.
A response with that cookie is sent to the browser, and the browser stores the cookie. This is an entirely opaque piece of data to the browser, it cannot do anything with it as it is compressed and cryptographically signed.
The browser will then send that cookie as is back to the Flask server every time a request is made. If the response to that request contains a new version of the cookie, then that'll be stored in the browser cookie storage. Any new request started after storing will then use the new cookie.
If however, you start a request before a response has been fully processed, or did not complete handling the response, then an older cookie could be used and your server decodes that older version with the changes not made.
Just set session.modified = True each time you modify your session.
This tells flask to update session after request.
I have been trying to learn Flask, and along the way the Flask-Login extension. I can make basic authentication work as expected. The issue that has me stumped involves the "Show my windows and tabs from last time" setting in Firefox and the "Continue where I left off" setting in Chrome. All the research I have done on this site and elsewhere indicates that these settings should only work for open tabs. So if you are authenticated and then close the tab, and then close the browser, the browser should only restore the session-only cookies for tabs that were open when the browser closed. However with both Firefox and Chrome the session-only cookie is still active when the browser is started again and I navigate to the page that is marked as #login_required. I should also mention that I am passing False to the login_user remember argument like so: login_user(user, remember=False)
I have played around with the idea of fresh logins with the Flask-Login extension thinking that closing the tab before closing the browser would surely mark the session as stale, but it doesn't. I examine the value of login_fresh() which returns true if the login is fresh, and it still returns True.
I found out how to make the login expire after a given time using session.permanent = True and then setting app.permanent_session_lifetime = 'so many minutes/seconds', which works perfectly, but isn't what I want.
I can live with the fact that Firefox / Chrome will remember session cookies for tabs that are open, but what I don't understand is why they remember session cookies for my site even when the tab is closed before closing the browser. Is this the expected behavior? Is it reasonable to expect the session cookie to be removed for my site when I close the tab first then the browser?
Is this the expected behavior? Is it reasonable to expect the session cookie to be removed for my site when I close the tab first then the browser?
Apparently yes, this is expected behaviour, and no you are not reasonable to expect such a thing. The behaviour you are seeing appears to be a deliberate design decision in the way the browsers implement "session restore" functionality.
See this Firefox bug from 2009 (eternalsession) Session restore can result in excessive session cookie lifespan that has many duplicates and no solution.
Or this Chromium bug from 2012 Session Cookies not cleared when Chrome processes closed with a status of WontFix
So, in short, I don't think there's anything you can do about this from the server side, no matter how awesome flask is :(
What Day says is spot on and your expectations should be correct. Nevertheless, there may be a work-around.
You can use a permanent session with a short lifetime (PERMANENT_SESSION_LIFETIME) and refresh its lifetime on every request (SESSION_REFRESH_EACH_REQUEST).
I think this is a rather new configuration (0.10 IIRC).