One of the oldest clichés in web application security is that, "It doesn't matter which framework you choose, if you know what you're doing". In my experienced opinion, off the back of a career in the web security industry, this notion is completely false!
This blog post explains why.
Good Developers Always Develop Secure Applications
Someone could try to write a secure web application using nothing but Brainfuck and enough time and effort. They could implement their own session handling and try to make it as secure as possible. But that sounds ridiculous, right?
When I say somebody could implement their own CSRF protection in PHP, it sounds perfectly normal because that's exactly what everyone keeps doing! However, this is still extremely unwise. In the same way, a secure session implementation should be one of the responsibilities of the framework. A secure CSRF protection implementation shouldn't have to be implemented by the developer.
Security of the Language, Security of the Framework
There is no perfect framework! Every popular framework has had vulnerabilities and the same is true for all popular web applications. But some applications have a better security track record then others and the same goes for frameworks. Apache Struts' OGNL Expression Injection, PHP's various low level vulnerabilities issues and Perl's serious flaws are good examples of these vulnerabilities.
PHP illustrates the point perfectly. The language itself has very many vulnerabilities, such as Zend_Hash_Del_Key_Or_Index Vulnerability or month of PHP bugs. Think about it. Even if the developer knew how to navigate around PHP's countless pitfalls, the application will still be vulnerable if there is a vulnerability in PHP itself. This is without mentioning the terrible design issues such as PHP type juggling or PHP object injection.
If you set a directory as protected and if your framework can't protect you because the attacker used a different HTTP Method, then that's not the developer's fault, it's framework's fault. That's why frameworks matter, because even if you build the most secure application, when your framework is vulnerable, so is your application.
Ask yourself these questions about your framework:
- Does your framework handle unicode characters correctly?
- Are functions unexpectedly affected by null bytes?
- Does it spill out sensitive data when you send one special character in a cookie?
All of these are problems concerning the framework – not your application. Choose a framework with a good security track record. Otherwise you'll have to read the source code of your application and that of the framework, including all its exposed API endpoints, the internal functions you call and the functions your framework calls each time a user issues a request (e.g. routing).
Framework Specific Issues
- You won't see many RFIs (Remote File Inclusion) in ASP applications because there is no easy way to introduce them there.
- You won't see many code execution problems (such as eval()) in ASP.NET applications because there is no easy way to do it.
- However in Classical ASP you have this problem. In PHP applications, even preg_replace was able to evaluate code with the /e modifier. And yes these problems manifest in real world applications, The PHPBB forum software was vulnerable to this flaw.
See? Framework-specific problems matter.
Secure by Default
There are frameworks that approach the design of certain functionality from a 'secure by default' angle. It's quite rare to see HTTP Header Injection (CRLF/HTTP Response Splitting) problems in ASP.NET for example. That's because by default all related .NET functions will refuse to accept new lines. You really have to go out of your way as a developer in order to introduce this vulnerability. However, you would be surprised how creative some developers can be when it comes to introducing vulnerabilities. The irresistible urge of some developers to introduce vulnerabilities previously thought to be impossible is something even the best framework can't fix. Sorry, but that's the truth.
Framework developers themselves are even prone to this phenomenon. The best example is Magic Quotes in PHP. An insane number of applications were vulnerable due to them, that's how much of a mess it was. It shouldn't have been there in the first place, that's why they eventually decided to deprecate it.
Inbuilt Security Features
I think every decent developer knows that rolling your own crypto is idiotic, yet somehow it's OK for developers to roll their own CSRF protection, SQL Injection filter, XSS protection library, for example. And if you ask any penetration tester worth their salt, they'll assure you that these developers keep failing miserably.
Here are the questions are your need to ask of your framework:
- Does it support parameterized SQL Queries (prepared statements)?
- Does it provide a way to separate data and the HTML and carry out the required encoding based on the output location in order to prevent Cross Site Scripting vulnerabilities?
- Does it provide a secure session implementation?
- Does it provide a secure authentication mechanism?
- Does it provide a secure way to execute OS commands? (separating parameters and the executable to avoid injections just like parameterized SQL Queries)
- Does it provide secure storage options? And path normalization functions?
- Does it provide a way to avoid email header injections?
- Is there any function which can protect against new line injections to write safe logs?
- Is there an inbuilt feature that will apply whitelisting on inputs?
I could go on, but you got the point. Unfortunately there is hardly a single framework that is completely secure by default. However, those whose developers who care about making the framework secure by default deserve more of our trust. This also means that you shouldn't trust a framework that leaves most of the points above to the user, or makes it hard to use them correctly, even if it's easier to use while you use it for development.
Documentation, Culture and Sample Code
Documentation and culture around a framework are also pretty important. Take a look at some older Tomcat JSP and IIS 6 ASP examples. Incredibly, all of them have several serious vulnerabilities out of the box. Apparently it's not enough to write vulnerable sample applications, they even need to be deployed automatically during setup so your environment can be vulnerable by default...
For example, many examples in the .NET documentation use parameterized SQL Queries, which sounds great, but the .NET documentation contains so many other flaws and terrible code snippets.
Many vendors have terrible documentation and neglect to provide secure code snippets. In order to increase clarity in the examples, some code samples have been stripped of important security and error checks.
Finally, when it comes to culture, there are other factors to consider. Let's take Perl as an example. You can see more OS Command Injections in Perl applications than possibly any other framework – because that's how most Perl guys roll. Pass it to an OS command, parse the output and print it to the screen. This is a quite rare practice in many other frameworks* but the Perl community seems to embrace it.
Required Time, Effort and Knowledge for a Secure Application
All of these factors affect the required time, effort and security knowledge necessary to develop a secure web application. If the framework provides built-in security for CSRF with one line of code, this immediately decreases the complexity of the application, and the required time for development and testing. Also, developers don't need to be security experts in order to implement such a check, which makes it easier for beginners to write secure applications.
Frameworks Matter In Web Application Security
Let's be honest. There's no perfect framework and there won't be one anytime soon, though we're getting there. Right now, the best solution is to choose the best framework available.
The frameworks I'm most familiar with are PHP, ASP and ASP.NET, where my examples come from. There are many other frameworks such as Ruby on Rails or Struts from which you can observe similar benefits or framework-specific problems.
* Although I need to note that due to many other configuration requirements that task might not be that easy in some frameworks hence not that popular. For example .NET might require several permissions to properly run an executable from an ASP.NET script.
** OK, they need to know about "Secure Cookies" but funny enough many of them still don't. So why not mark all cookies set over SSL as secure and when their code doesn't work they can fix(!) it, at least this way it'll be secure by default and maybe developers will ask themselves "What the hell is a secure cookie? and why would I need it?"