Django and SQL Injection with example - django

I'm receiving an incoming POST from another site, below is how I currently get it. I'm new to Django, but few things jump out at me and I'm wondering if I should be concerned.
SQL Injection: As I cannot clean the post data is using request.POST['message'] open is SQL injection?
Security: is there a better way to do this?
#csrf_exempt
def incoming_message(request):
if request.POST:
# Match incoming keyword.
keyword = Keyword.objects.get(keyword=request.POST['message'])

Django has built in SQL injection prevention in its queryset driver.
By using Django’s querysets, the resulting SQL will be properly escaped by the underlying database driver.
Because you're using a queryset, you're covered for SQL injection. You may want to check that you're comfortable with the XSS protection that Django provides. Depending on how you use the data, you may need to escape it yourself.

Related

Django app has multiple database and multiple user

I have written one Django cloud based app. This app will have multiple user and for them multiple database, so that their data should be separate and they can save only to same database.
1) How can we implement it
2) How to automatically one user from login page to assign the database to write on it.
I don't have a complete answer, since you do not give a lot of detail. But here are a couple ots that f hinDjango supports custom database router implementations. A database router is a class that helps django decide which database to use for a particular model. Unfortunately I don't think this mechanism is granular enough for your needs. You can also specify the database to use in your code by using using(name) queryset method and save(using=name) form of save() method for instances. Of course this also means that some features of Django are going to be unvailable to you, since you cannot always expect to have a user. Look at the docs here for more info
https://docs.djangoproject.com/en/dev/topics/db/multi-db/

django form fields clean method and security

My web application has a lot of forms. I don't use django form classes, since my forms are somewhat complicated (involve with a lot of javascript), so I write the forms and handle them at server by myself.
My question is about "cleaning" the fields data.
I know django forms has a clean() method which supposed to sanitize the data.
But isn't django built-in ORM already clean the data from SQL injection type attacks?
If I have similar code:
field = request.POST['field']
record = SomeModel.objects.get(pk=record_id)
record.field = field
record.save()
I POSTed a < script> tag with some javascript to my server, and I couldn't find any security hole here, since django sanitize the data that is printed in the template.
so what the clean() method adds here exactly, and does this code has any security problems?
The clean() method mainly validates the form data i.e. it verifies if the data inserted in the form fields fits the type of the field and respects some patterns. The SQL injection protection is build into ORM. So if you use django ORM querysets you should be protected from SQL injection attacks. As per docs:
By using Django’s querysets, the resulting SQL will be properly
escaped by the underlying database driver.
Only if you want to run raw SQL or custom SQL queries you have to properly escape any parameters that the user can control.

Django - Runtime database switching

In my work we want to run a server with multiple databases. The databases switching should occur when you acces a url like http://myapp.webpage.com or http://other.webpage.com. We want to run only one server instance and at the moment of the HTTP request switch the database and return the corresponding response.
We've been looking for a mantainable and 'Django-friendly' solution. In our investigation we have found possible ways to do this, but we have not enough information about.
Option 1: Django middleware
The django middleware runs each time the server receive a HTTP request.
Making a database switch here could be the best option but using django database routers as far as I know only allow to change the database for a model or group or models.
Another option is to set a django model manager instance in the middleware and force all models to re-assign the objects attribute from an added attribute in the custom middleware.
My last option is to create a new attribute in the request object received by the middleware that return the database alias from settings.py and in each model query use the using method.
Option 2: Class-based View Mixin
Create a mixin that use the past three options, but I the mixin must be set in ALL the Class-based views. If a programmer forget to set the mixin and it comes to a production server, the data could be (or stop being) in the right database, and I don't wanna take the risk.
Option 3: Changing the database settings in runtime
This option works but Is not recommended and is too risky.
UPDATE:
How this works?
middlewares.py
import django.conf as conf
import os.path
class SelectDB(object):
def process_request(self, request):
print request.META['HTTP_REFERER']
file_database = open("booklog/database.txt", "r")
database = file_database.read(10)
file_database.close()
if database != 'default':
conf.settings.DATABASES['default']['NAME'] = database
Any information that help us to solve will be greatly appreciated.
Answer (it worked for me)
The question was already answered here, in stackoverflow. I'd love this functionality were in django. It was a bit hard to find the way to make this possible.
I think that is important to comment the great work that Wilduck made with the django plugin django-dynamic-db-router, it's a great plugin that makes possible this operation in (a bit) different way.
Thanks a lot to #JL Peyret and #ire_and_curses.
And as an answer to #ire_and_curses. At least in this moment, in the project I'm working it's what we need. In previous projects we needed a similar behavior and made one server per instance was terrible to mantain and update each server, even automating the process.

Is data in Django’s request.POST object sanitised, at least enough for direct use in an ORM query?

I’m building a web forum using Django, including the built-in authentication module.
I’m using the built-in UserCreationForm to register users. However, as I‘ve decided to use e-mail addresses as the sole way to identify users, I’m generating a username for users before registering them.
To account for users who have already registered, before I generate a username, I check that a user doesn’t exist with the supplied e-mail address.
Is it safe to use the supplied e-mail address, directly from request.POST, in a query to the Django ORM, without doing any sanitisation on it? I can’t see anything in the documentation about data in request.POST being sanitised, but the ORM protects against SQL injection. Are there other potential attacks that I’m missing?
request.POST itself is not sanitized, but the Django ORM automatically sanitizes anything your throw at it, so yes, it's safe to simply pass it right to the ORM. Just be careful with using raw or extra.

Django Mongodb Engine : Authentication, Sessions ans User Model

I'm new to Django and Mongodb seems really cool and I have a few
questions ! I'm using Django nonrel with Django Mongodb Engine.
I hope I'll not make too many mistakes :)
1 ) Are the Django user authentication system and the Django Session
system working fine ? Because I see on allbuttonspressed.com that
there is a problem with authentication and admin interface and the
part with the 3rd party written authentication backend makes me think
that the django authentication system doesn't work with mongodb :
You can only edit users in the admin interface if you add
"djangotoolbox" to your INSTALLED_APPS. Otherwise you'll get an
exception about an unsupported query which requires JOINs.
Florian Hahn has also written an authentication backend which provides
permission support on non-relational backends. You should use that
backend if you want to use Django's permission system.
2) If the authentication system works fine, how can I add fields to
the user model ? I saw on the Django docs that to achieve that the way
to go is to define a model with a OnetoOnefield to the user model
( "user = models.OneToOneField(User)" ) and define the other fields we
want in that model. I get it that must be the right way with SQL
databases. But with NoSQL like mongodb that just seem wrong to me, if
I'm not mistaken it creates a new collection and puts in each document
an user field used to link the document to the document in the User
collection ( exactly like a foreign key ). That doesn't seem to be a
NoSQL way at all ( Well It's just my feeling but since I'm just a
beginner I may be wrong, don't hesitate to correct me ). Is there a
recommended way to add fields directly to the User model ?
3) When the Model is used in Django, it puts all the fields in the
document even if they are empty right ? Isn't that a waste of space to
write down a lot of fields names in documents if they are empty ?
4) This question is more about Mongodb itself than the engine but I'll
ask it anyway, you may have the answer : How much extra space does it
take to index a field in a collection ?
Didn't think I would have written so much, I hope some of you had the
courage to read me !
Thanks in advance,
Nolhian
Only a partial answer as I don't use MongoDB.
I'm using django-nonrel in a Google AppEngine project. I'm using those other custom apps like "djangotoolbox", and some backends for GAE. Admin panel and standard Django authentication are working very well. I suspect it's the same for MongoDB (like mentioned in the quotation you have provided)
You're right. The standard approach is definitely good for relational databases, but might not work or work inefficiently for NoSQL databases. The typical scenario is to duplicate the data to another table, so you don't have to do JOINs. I think you can simply subclass the User model and add your fields to your custom model (docs).