Django csrf verification fails after switching off https - django

I am using Django 1.7.1 , I made a single change outside of my django web app , i.e switched off https inside nginx since my django webapp moved within the company firewall.
I made no other changes to the webapp , like in any of the django code: I am testing the webapp access via the company vpn.
The home page , which is a form loads fine when I go to http://mywebapp.mycompany.com.
Now , When I hit submit. I see the CSRF verification failure with a reference to https://mywebapp.mycompany.com! as detailed below. I even get the error in incognito mode to rule out any old cache issues.
I wanted to know the source of the error and feel it is outside of my webapp and within some vpn configuration/ browser cache / some other cache.
I have checked the possible reasons for CSRF failure given in the django message , and am not doing any of those "bad" things.
Any ideas on how to troubleshoot this. I want to know whether this is a VPN config problem , an nginx config problem or a django "best practices" problem.
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
Referer checking failed - http://mywebapp.mycompany.com/ does not match https://mywebapp.mycompany.com/.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
I am not doing any of these. My form uses :
<form role="form" action={% url "sequence_input" %} data-persist="garlic" data-destroy="false" method="post" enctype="multipart/form-data">{% csrf_token %}
The calls to the form are using RequestContext:
return render(request,'sequence_input_form.html',{'form':form})
And I have the following context processors:
TEMPLATE_CONTEXT_PROCESSORS= ("django.core.context_processors.static",
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",)
My Nginx conf indicating commented lines.
server {
listen 80;
listen [::]:80 ipv6only=on;
#listen 443 default ssl;
charset utf-8;
# Make site accessible from http://localhost/
server_name [my server ip];
#if ($ssl_protocol = "") {
# rewrite ^(.*) https://$server_name$1 permanent;
#}
#if ( $scheme = "http" ) {
#return 301 https://$server_name$request_uri;
#}
#ssl_certificate /home/mywebapp/mywebapp/mywebapp_cert.crt;
#ssl_certificate_key /home/mywebapp/mywebapp/mywebapp_key.key;
#ssl_certificate_key /home/mywebapp/mywebapp/harijay/mywebapp_webhop_org.key;
location / {
uwsgi_pass django;
include /home/mywebapp/mywebapp/uwsgi_params;
uwsgi_read_timeout 60000;
root /home/mywebapp/mywebapp;
#index pam_lister/templates/sequence_input_form.html;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
location /static {
autoindex on;
alias /home/mywebapp/mywebapp/static/;
}
}

Related

NGINX throws 404 and wont load static

Hopefully, Y'all can help me with this one and hopefully I am in the right areas to post this. Just recently began learning Django and I am trying to get it deployed to Linux. I have been using gunicorn and nginx for this deployment and for the most part I have been successful. I am able to successfully deploy and interact with my app, navigate pages and interact with some of the post requests. The only thing I have been banging my head around trying to figure out what is going on with my static files. All of my css and images do not display currently and I have tried searching everywhere for the resolution. I have tried using an alias in the nginx file and I have made sure that my static root and URL is fine, nothing i have tried has done the trick. the weird this is, when looking at the access logs from nginx it shows the Get request going to the correct file and path, but shows 404? I am at a loss here lol! What is really weird is that the static folder contains a few csv's that are processed and served by a view those work correctly so I am confident that the url and root in setting.py is correct. Some of the other things I have tried include setting STATIC_URL to '/' and '/Static_File_Storage' neither worked one gave me an error about media url and the other gave me a permission denied error. This is also for a network-only site and won't be accessed by anyone other than a few employees so I am not worried about having it pulling from home.
**NGINX FILE:**
server {
listen 80;
server_name redacted;
location = /favicon.ico { access_log off; log_not_found off; }
location /Static_File_Storage/ {
alias /home/beachhouse/PycharProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}}
**setting.py**
STATIC_ROOT = os.path.join(BASE_DIR, "/Static_File_Storage/")
STATIC_URL = 'home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/'
**Actual Location of File:** /home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/css/style.css
**output on logs: "GET** /home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO/Static_File_Storage/home/beachhouse/PycharmProjects/BH_Django_Project/BH_DJANGO_Static_File_Storage/css/style.css HTTP/1.1" 404 1226
**Static Tags in HTML:** {% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"/>
<img class="login_img" src="{% static '/logo.png' %}" alt="logo">
View call for static: df = pandas.read_csv(static('Flash_Changes.csv'))
Change STATIC_URL to "/Static_File_Storage/".

Adding domain path to django html templates

I am serving a django app with a combination of nginx reverse proxy and waitress. In the nginx configuration the app is linked via a location:
location /app/ {
proxy_pass http://localhost:8686/;
}
While the app runs on via waitress on port 8686.
Now, if I go to the domain.com/app, I the index page is served correctly. Though, my django html template contains the following link:
<p> You are not logged in.</p> <button>Login</button>
When I press that button I get to
domain.com/accounts/login
but it should be
domain.com/app/accounts/login
I wonder how to change the code so that it works independently of where the app is linked.
In urls.py the urls are included like this:
urlpatterns: = [...,
path('accounts/', include('django.contrib.auth.urls'))]
Define the url in urls.py (most probably you've already done this) and then use reverse in templates:
<button>Login</button>
Then rewrite URLs in nginx to make your app think that you're accessing /accounts/login instead of /app/accounts/login:
location /app/ {
rewrite ^/app(.*)$ $1 last;
proxy_pass http://localhost:8686/;
}
Docs:
https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#std:templatetag-url
https://www.nginx.com/blog/creating-nginx-rewrite-rules/

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

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.

Django/Apache address problem

I have a django app running on http://djangohost/appaddress. I'd like the project to be available at http://differentaddress/app . Currently I'm able to run app at the desired address but using {% url %} templatetags gives me improper address in the form http://differentaddress/app/appaddress. Also when I go to django app address directly all {% url %} links are in the form http://djangohost/app/appadress How can I change this ? I have these entrances in apache conf :
ProxyPass /app/ http://djangohost/appaddress/
ProxyPassReverse /app/ http://djangohost/appaddress/
You'll probably have to tell Django where it is running by manipulating SCRIPT_NAME
http://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#force-script-name
Or, if you want to keep things within Apache, you may give a try to mod_proxy_html - disclaimer: haven't used it myself, but it does claim to rewrite links in HTML pages
Maybe not a proper solution but still some workaround for the problem without interfering with apache's settings. Tested with mod_msgi and it works like a charm. Here's the link :
http://fromzerotocodehero.blogspot.com/2011/01/using-proxypass-with-django-project.html . Basically I've overriden built in url function here creating custom urlc temlpatetag. In tag's code I've added line replacing first occurence of unwanted app name with empty sign.
So you want to "mount" a Django site on a sub URL path? I already tried this with Apache and mod_proxy, and it was kind of a nightmare to find out. Here's what I have come up with (probably not complete or perfect):
# In your scenario
FORCE_SCRIPT_NAME = "/app/"
# End of settings
_prefix = (FORCE_SCRIPT_NAME or "")
LOGIN_URL = _prefix + LOGIN_URL
LOGIN_REDIRECT_URL = _prefix + LOGIN_REDIRECT_URL
LOGOUT_URL = _prefix + LOGOUT_URL
ADMIN_MEDIA_PREFIX = _prefix + ADMIN_MEDIA_PREFIX
Obviously, this prepends "/app/" to the most important hardcoded site URLs, plus it sets FORCE_SCRIPT_NAME to ensure that {% url something %} will result in an absolute URL of "/app/something", for instance.
This worked for me using mod_wsgi for the Django site and ProxyPass/ProxyPassReverse for the "mounting". Try it out and give me feedback, I'm interested whether this is a general solution.

Unable to make a domain redirection in Django from example.com to www.example.com

I get the following message when I browse to example.com
500 - Internal Server Error
I get my 404 error message when I browse to www.example.com which indicates my site is alive.
How can you make a domain redirection without .htaccess by Django from example.com to www.example.com?
My urls.py
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
(r'^home/', include('index.html')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/(.*)', admin.site.root),
)
[edit]
I have the following answer from Djangohosting:
Remove the website proxy for [example.com] and add [example.com] in the aliases section of the [www.example.com] website.
I am not completely sure what it means.
How can you remove the website proxy for example.com?
Where can you find the aliases section of the website www.example.com?
I don't know if it solves all your problems but if you want to do it via django, try a middleware
from django.http import HttpResponseRedirect
class WWWRedirectMiddleware(object):
def process_request(self, request):
if not request.META['HTTP_HOST'].startswith('www.'):
return HttpResponseRedirect('http://www.example.com')
Remember that it must be executed before any other middleware.
Based on this one, didn't test it.
Checking out PREPEND_WWW setting might help.
The 500 Internal Server error is likely caused by this line:
(r'^home/', include('index.html')),
The include() function is a way to include other URL config files, not static HTML files. You'd have to either serve index.html as a static file at the given URL (/home), or write a view that simply renders the file.
I get the following message when I browse to example.com
500 - Internal Server Error
I get my 404 error message when I browse to www.example.com which indicates my site is alive.
It is likely the other way around. The 500 message means that your site is active, but giving an error. What you have to understand is that the example.com/www.example.com part of the url serves to find which server to connect to. By the time your Django application gets called, this part has already been completed, so there os no way to do this from Django.
Instead, you want to set up www as a subdomain of example.com and make them point the same place. See the first example here: virtualhosts examples
UPDATE I just noticed that you stated that your 404 was showing up, so ignore the first two sentences. Either way, the solution would likely be the same. :-)