Preventing IDOR in Django
Preventing IDOR in Django
Basically I got some basic internals about Django framework since most of my code reviews operations are with web applications written in Django, in this blog you will get the required knowledge in order to
- Find IDORS in your Django project
- Patch it
Insecure Direct Object Reference aka IDOR, as we know Django is “secure web framework” for example you won’t find any kind of SQL Injections vulnerabilities within the project till the developer is executing custom SQL directly in the low level which could lead to SQL Injection within the app , also Django templates escape the HTML in order to prevent XSS , till the user use “safe” flag in the render engine with untrusted data , this also could lead to XSS
execution custom SQL directly in the low level
All of the above mentioned scenarios are not common to see in Django projects, because simply it won’t pass from QA review or even normal code review
What’s IDORs
it’s not the blog topic but you can check other resources explaining about how you can exploit IDORS and how you can Exploit it and find it in a black-box testing environment
Common Reasons
you can check any bug bounty platform programs history about what kind of bugs researchers always find, probably it will be an IDOR based modern web frameworks now are kinds safe by default till someone miss the core point and just passing things into functions without any knowledge about how this function work
the Query above looks too common thing to see within Django apps according to official Django Documentation
you can call get() but it raises HTTP 404 instead of the model’s DoesNotExist exception same as “Project.objects.get(pk=id)” but developers are using it for less HTTP 500 Server error 🙂 and also it’s better than using DoesNotExist exception which requires more lines of code
this line casing an IDOR Bug since if you wanted to restrict access this object to a specific user stored in the database as Foreign Key this query won’t work because simply it’s just checking for the project ID, and it will return the object till it’s exist
the same thing applies to Project.objects.get(pk=id)
Patch it
the patch is a really simple thing to do and we still on the same line 🙂
exploring get_object_or_404
since the function take *args, **kwargs you can pass user condition which’s probably going to be like this one
looks better without IDORs; but, is that really effective? going with all of the views within the project and patching them? with big projects, that’s could be a problem
Secure By Default
in this section, I will share my personal experience about securing Django projects against IDORs using Django using decorators
How It’s Work
- Take the target Model in our example is Project
- it can work with normal views functions well as class-based views
- trying to get fields related to the user foreign key
- getting URL parameters in our example is “id”
- building a query that trying to get the object with the user at the same time
- if the query failed it should log the request and return PermissionDenied view
Articles from the workshop