Embedded django site seems to have a problem with its CSP settings - django

My django(2.1) app needs to be able to be embedded in an iframe in a partner's website. I'm currently running it on google app engine where I have the following app.yaml settings:
handlers:
- url: /.*
static_dir: static/
secure: always
http_headers:
Content-Security-Policy: "frame-ancestors 'self' partnersite .com *.partnersite.com www.partnersite.com;"
I can now access the login page through the partner site but when I try to log in I get the following error:
CSRF verification failed. Request aborted.
Reason given for failure:
CSRF cookie not set.
The templates have {% csrf_token %} tags. I'm stumped, if anyone has any help or feedback please let me know.

Related

CRSF cookie not set in iframed Django View within another site

I have a Django app with about a dozen views that I am currently hosting on Heroku. I can do POST requests just fine to the app when directly going to the app url, and I have the 'django.middleware.csrf.CsrfViewMiddleware' enabled. I am running Django 2.1
I am currently having an issue where I am trying to embed this Django app within an iframe, on another site that I host on Weebly. I always get a 403 error when trying to do a post on any of the Django forms. The reason is "CSRF cookie not set."
I am doing this through Chrome on Ubuntu. I checked the Applications tab in the Developer console, and do see the csrftoken key-value pair set in the cookie for the Heroku domain. The Weebly domain does not contain the csrftoken key-value pair. I figured it would just use the cookie from the Heroku app domain and use the csrftoken, but that doesn't appear to be the case.
In Django, here are my settings regarding CSRF:
CSRF_COOKIE_SECURE = False
CSRF_TRUSTED_ORIGINS = ['example123.herokuapp.com',
'app123.weebly.com']
I REALLY don't want to disable security or use the csrf_exempt decorator, as that feels like a hack. I am pulling my hair out on this one!
EDIT:
{% csrf_token %} is in the form, and I can see the hidden field "csrfmiddlewaretoken":
<input type="hidden" name="csrfmiddlewaretoken" value="XXXXXXXXXXXXXXXXXXXXXXywkFTfTC9ttYiOTD0O8uF49SvRjaUWgWeLU0h2PjP2">
There are two different things with csrf in django
1. Csrfmiddlewaretoken : {% csrf_token %}
example of set-token header
2. CSRFcookie : I don't think that you did this one.
example of same request giving different csrf-token
here the images shown are both the examples of one of my app for a specific request
We do often confuse second with the first one. In the second case, the server sets a cookie in the first get request with a csrf token (this is a cookie and not the csrfmiddlewaretoken ), it needs to be sent every-time for csrf cookie verification. This is done by the browser itself and we mostly don't notice it. However the problem arises with using CORS (different origins of request like android/angular app etc).

Acquiring CSRF token from Django when index.html is served by nginix

I have a React SPA with a Django backend. Like most SPAs, there is an index.html file that needs to be served. But the problem is that this file is served with nginx, so user does not obtain csrf token required to make api calls. I don't really want to serve index.html, as it would require separating the file from the rest of npm run build output and break the "just put it in /static/ directory" workflow, and also for caching reasons. Is there any other workaround?
CSRF token is always updated with each page load. It has to be served by django since django is the application that provides and validates it. Place the index.html file in your django templates folder, serve it with your index view, translate CSRF token to javascript code and use it in your ReactJS code
index.html
...
<body>
<script>
var csrftoken = '{{ csrf_token }}';
</script>
...
</body>
...

django posts receive CSRF verification failed after switching to load balancer

I have a working login template that does a post and looks like:
<form action="" method="post">
{% csrf_token %}
<br>
{{form.email}}
<div class="text-center">
<button type="submit">Login</i></button>
</div>
</form>
My SSL settings look like:
ssl
SECURE_SSL_REDIRECT = False
SECURE_HSTS_SECONDS = 3600
SESSION_COOKIE_SECURE = False
SECURE_PROXY_SSL_HEADER = None
CSRF_COOKIE_SECURE = False
I made two changes. I switched to an aws ec2 elastic load balancer and from https to http.
Now I am getting an error:
Forbidden (403) CSRF verification failed. Request aborted.
You are seeing this message because this site requires a CSRF cookie
when submitting forms. This cookie is required for security reasons,
to ensure that your browser is not being hijacked by third parties.
If you have configured your browser to disable cookies, please
re-enable them, at least for this site, or for 'same-origin' requests.
Does anyone know why this is occurring?
I must have a stale cookie. When I go to Chrome incognito mode, all works as would expect with a 200 response.
Forbidden (403)
CSRF verification failed. Request aborted.
You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.
If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for 'same-origin' requests.
More information is available with DEBUG=True.

CSRF verification failed. Request aborted - Shopping cart configuration

I'm trying to enable Payment module for courses and when I'm clicking checkout, I'm getting "CSRF verification failed. Request aborted." . I've tried adding my domain to "Home › Cors_Csrf › X domain proxy configurations › XDomainProxyConfiguration()" in Django admin panel. Even modified lms.env.json to add "ENABLE_CROSS_DOMAIN_CSRF_COOKIE": true, " ... still facing the issue. Can anyone please help.
Google group message link : https://groups.google.com/d/msg/edx-code/4VnLJG-raPE/llF1PDG9AQAJ
Possibly you're not including the CSRF token in your form. In your template, it should look like:
<form action="post">
{% csrf_token %}
{{form.as_p}}
</form>
I don't know the library you're using, that was just general Django commentary. Hopefully it's helpful.

Unable to jQuery $.post data to a view in django due to CSRF

Before posting this i've tried every solution method posted online, including solutions on Stackoverflow and Django. (I think the reason for error perhaps is due to the fact that i'm on a newer verison of jQuery and django and most solutions are dated, using jQuery 1.9 and django 1.5.1)
Here are some URL's to solutions that don't work:
Django CSRF check failing with an Ajax POST request
How to use $.post with django?
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Any help would be appreciated. Another possibility for error is the fact that i'm not actually sure where to place these snippets exactly. So far i've pasted everything inside the jquery on document load, i've also tried pasting the code in the very start of the .js file. (My javascript code is fragmented in chunks, some are seperate .js files and some are inline with the html being rendered with django context, so any solutions with "{{ csrftoken }}" are bad.
Thanks!!
The CSRF token only gets set if it's present in the template or if the view is decorated with ensure_csrf_cookie(). Putting {% csrf_token %} in index.html will make it apply for all your pages.
From the docs:
The CSRF token is also present in the DOM, but only if explicitly included using csrf_token in a template.
...
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie. This is common in cases where forms are dynamically added to the page. To address this case, Django provides a view decorator which forces setting of the cookie: ensure_csrf_cookie().
Can you try this:
$.ajax({
type: "POST",
url: '{% url "some_url_which_accepts_post" %}',
data: {'csrfmiddlewaretoken': '{{csrf_token}}', 'comment_id':1},
success: function(data, textStatus){
//something
},
});