I am having a weird problem with Django. I set certain cookies on the client, but those cookies do not appear in the Django request.
The cookies properly appear in the client as follows:
"class_year_only=yes; email_status=yes; exit_status=yes; class_year_only_status=yes; nmstat=1448946715685; __utma=96992031.1943662208.1449612961.1449621554.1449704668.3; __utmz=96992031.1449612961.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); csrftoken=Oe2A6Qn7pwUshDEFAhyNa4dtGRajVe4S"
However, the Django request only shows the following cookies:
"{'csrftoken': Oe2A6Qn7pwUshDEFAhyNa4dtGRajVe4S, '__utma':96992031.1943662208.1449612961.1449621554.1449704668.3, '__utmz':96992031.1449612961.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none), 'nmstat':1448946715685}"
Why aren't the other cookies being sent?
I figured out the problem. I needed to set path to /. The path in the client side cookie, used a subdomain which was the cause of the problem. Not sure why, as the subdomain was correct.
Related
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.
I am learning django and trying to complete my first webapp.
I am using shopify api & boilder plate (starter code) and am having an issue with the final step of auth.
Specifically, the redirect URL -- it's using HTTP:// when it should NOT and I don't know how to change it..
#in my view
def authenticate(request):
shop = request.GET.get('shop')
print('shop:', shop)
if shop:
scope = settings.SHOPIFY_API_SCOPE
redirect_uri = request.build_absolute_uri(reverse('shopify_app_finalize')) #try this with new store url?
print('redirect url', redirect_uri) # this equals http://myherokuapp.com/login/finalize/
permission_url = shopify.Session(shop.strip()).create_permission_url(scope, redirect_uri)
return redirect(permission_url)
return redirect(_return_address(request))
Which is a problem because my app uses the Embedded Shopify SDK which causes this error to occur at the point of this request
Refused to frame 'http://my.herokuapp.com/' because it violates the following Content Security Policy directive: "child-src 'self' https://* shopify-pos://*". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
How do i change the URL to use HTTPS?
Thank you so much in advance. Please let me know if I can share any other details but my code is practically identical to that starter code
This is what the Django doc says about build_absolute_uri:
Mixing HTTP and HTTPS on the same site is discouraged, therefore
build_absolute_uri() will always generate an absolute URI with the
same scheme the current request has. If you need to redirect users to
HTTPS, it’s best to let your Web server redirect all HTTP traffic to
HTTPS.
So you can do two things:
Make sure your site runs entirely on HTTPS (preferred option): Setup your web server to use HTTPS, see the Heroku documentation on how to do this. Django will automatically use HTTPS for request.build_absolute_uri if the incoming request is on HTTPS.
I'm not sure what gets passed in the shop parameter but if it contains personal data I'd suggest to use HTTPS anyway.
Create the URL yourself:
url = "https://{host}{path}".format(
host = request.get_host(),
path = reverse('shopify_app_finalize'))
But you will still need to configure your server to accept incoming HTTPS requests.
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
To give some more context:
We have an fb app which gets served under:
domain.com/fb/
and we have the normal site which gets served under
domain.com
Our fb app serves domain.com/fb/ in an iframe and is accesiable via:
apps.facebook.com/ourappname/
I'm currently having an issue with only IE, which caused request.user to be an anonymous user, even when the user is logged in (Only in IE) everything works fine in all other browsers. The reason for the request.user to be an anonymous is that the session cookie is not being set. I verified this by inspecting the cookies in IE and also django-debug-toolbar showed me that.
So how can I fix this issue?
The P3P headers are set:
response['P3P'] = 'CP="IDC CURa ADMa OUR IND PHY ONL COM STA"'
return response
They are also added by apache itself so kind of double just wanted to make sure it worked.
It's known security behavior of IE with iframe web sites. This could help:
Cookie blocked/not saved in IFRAME in Internet Explorer
I'm using tornado and the TwitterMixin and I use the following basic code:
class OauthTwitterHandler(BaseHandler, tornado.auth.TwitterMixin):
#tornado.web.asynchronous
def get(self):
if self.get_argument("oauth_token", None):
self.get_authenticated_user(self.async_callback(self._on_auth))
return
self.authorize_redirect()
def _on_auth(self, user):
if not user:
raise tornado.web.HTTPError(500, "Twitter auth failed")
self.write(user)
self.finish()
For me it works very well but sometimes, users of my application get a 500 error which says:
Missing OAuth request token cookie
I don't know if it comes from the browser or the twitter api callback configuration.
I've looked through the tornado code and I don't understand why this error
appears.
Two reasons why this might happen:
Some users may have cookies turned off, in which case this won't work.
The cookie hasn't authenticated. It's possible that the oauth_token argument is set, but the cookie is not. Not sure why this would happen, you'd have to log some logging to understand why.
At any rate, this isn't an "error," but rather a sign the user isn't authenticated. Maybe if you see that you should just redirect them to the authorize URL and let them try again.
I found the solution !!
It was due to my DNS.
I didn't put the redirection for www.mydomain.com and mydomain.com so sometimes the cookie was set in www. and sometimes not then my server didn't check in the good place, didn't find the cookie and then send me a 500 error.
The reason this was happening to me is that the Callback URL configuration was pointing to a different domain.
Take a look at the settings tab for your application at https://dev.twitter.com/apps/ or if the users getting the error are accessing your site from a different domain.
See: http://groups.google.com/group/python-tornado/browse_thread/thread/55aa42eef42fa1ac