Thursday, October 20, 2011

Web App Security: Django and the OWASP Top 10

Security threat: Neutralized.
At my company, Panoptic Development, we've built several applications for the healthcare industry.  Since we often deal with sensitive patient medical data, web application security is a huge concern.  Enter the OWASP Top 10, a collection of best practices for web application security.

What's OWASP?
From Wikipedia:
The Open Web Application Security Project (OWASP) is an open-source application security project. The OWASP community includes corporations, educational organizations, and individuals from around the world. This community works to create freely-available articles, methodologies, documentation, tools, and technologies. 
What's the Top 10?
From the OWASP Wiki:
The OWASP Top Ten provides a powerful awareness document for web application security. The OWASP Top Ten represents a broad consensus about what the most critical web application security flaws are. Project members include a variety of security experts from around the world who have shared their expertise to produce this list. Versions of the 2007 were translated into English, French, Spanish, Japanese, Korean and Turkish and other languages. Translation efforts for the 2010 version are underway and they will be posted as they become available....As you help us spread the word, please emphasize:
  • OWASP is reaching out to developers, not just the application security community
  • The Top 10 is about managing risk, not just avoiding vulnerabilities
  • To manage these risks, organizations need an application risk management program, not just awareness training, app testing, and remediation

No Easy Answer
Make no mistake - robust security is the result of consistent, ongoing code review, infrastructure expertise, and a broad knowledge of web programming, not a one-time checklist.  Still, when you're dealing with sensitive data, and especially when several organizations work on the same codebase, it's important to have mutually-accepted security standards.

Django:  Frameworks to the Rescue
Full-stack web development frameworks like Django are great for helping a team manage security concerns.  Let's investigate how Django's security features relate to the 2010 OWASP Top 10.  If you need background information on the vulnerability types themselves, I included wikipedia links.

I should also stress that this isn't an exhaustive look into every possible security vulnerability; this just explores some of the most important ways that Django mitigates (or doesn't mitigate) major security concerns.

  1. Code Injection:  For most Django applications, the primary code injection risk is SQL injection.  Django protects against SQL injection through its ORM abstraction layer, which automatically escapes input.  Note that it's possible to perform raw sql queries with Django, any any such code should be manually audited for if it interacts with direct user input.  Though raw SQL is needed occasionally, especially for optimization, it's generally a code smell in a Django application.

    If your application interacts with any other backends, like LDAP, you'll want to investigate those third-party libraries separately.  Client-side javascript is also mitigated through its templating system; see #2 below.

  2. Cross-site scripting:  Generally, the most important way to mitigate XSS is to prevent unescaped user input from making it into your application's rendered HTML. Django’s templating system facilitates this by automatically excaping all variable values.  If you don't want to escape something on the front end, you have to explicitly tell Django not to escape it.  In your code reviews, you can concentrate more on the few areas of your app where you don't escape user input.

  3. Session hijacking:  With the default Django SessionMiddleware, the framework doesn't allow any session data in the url.  Session IDs are also stored as hashes, mitigating brute force attacks.

    While you'll still want to ensure your code doesn't expose direct session data to the user in any way, Django makes it difficult to expose that information.

  4. Insecure direct object references:  Django has several mechanisms in place to mitigate IDORs.  It provides a special "slug" field if you don't want to pass object IDs around as parameters.  Django 1.2 also lets you explicitly name read-only fields in the admin, so you can prevent users from hacking together forms that alter protected  data.

    Note that you'll still want to manually audit your code to expose areas where users can access arbitrary object data, especially outside of the admin.

  5. Cross-site request forgery:  Django has built-in CSRF protection middleware, so it would be extraordinarily difficult for an attacker to maliciously submit a form to your site using an authenticated user's credentials.

  6. Security misconfiguration:  This is one item that is largely outside the domain of the web framework itself; it's more about the application's deployment environment.  You need to keep up with Python security updates, Django security updates, and keep track of any third-party libraries you use for security updates.  You need to disable ports/services you don't use, and more.  With complex apps, this can be a huge job.

    Fortunately, there are great, frequently-updated blogs for both the Python and Django core teams where you can keep track of security updates.  It's also easy to follow security announcement lists for your web server (e.g. apache, nginx) or operating system to keep track of security updates.

  7. Insecure cryptographic storage:  If the only secure information you're encrypting is user password data, you're all set if you use Django's built-in user authentication.  Django encrypts password data using SHA1 by default, but also supports MD5 and crypt out-of-the-box.

    If your application directly stores or manipulates any sensitive user data, you'll need to audit that code manually.  Fortunately, OWASP maintains a great cryptographic storage cheat sheet to help you along the way.

  8. Failure to restrict URL access:  Django has great built-in support for restricting access to specific content.  Access is always controlled at the view level, before anything is rendered.  You're able to restrict access for specific actions or for entire views.  Note that you'll still want to audit each url/action in your app to ensure that you're restricting access the way you intended.  It's easy to miss a @login_required decorator or forget to lock down an AJAX action.

  9. Insufficient transport layer protection:  In many cases, strong transport layer protection means using SSL.  Though this falls outside the domain of Django itself, the framework does provide some help:  Django supports the secure cookie protocol (PDF link to research paper), and also allows developers to force the use of secure cookies over HTTPS.

  10. Unvalidated redirects and forwards:  Because of Django's robust, built-in URL access restriction (see #7), it would be very hard for an attacker to take advantage of unvalidated redirects.  Again, since access is handled at the view level, you can't [easily] redirect users to a different url on your site without access control.

    Additionally, Django's built-in user authentication system doesn't allow off-site redirect links as url parameters.  Note that you'll still want to audit your code for any manual use of redirect links in URL parameters.


Kristian Erik Hermansen said...

web2py is better.

Francisco Vieira said...


Unknown said...

These are the most important security concerns with these web app. Professional developers in web applications development company must find out the perfect solution for these security issues.