HTML5: Risky Business or Hidden Security Tool Chest?

I was lucky to be allowed to present about how to use HTML5 to improve security at the recent OWASP APPSEC USA Conference in New York City. OWASP now made a video of the talk available on YouTube for anybody interested.

http://www.youtube.com/watch?v=fzjpUqMwnoI

 

Safer Software through Secure Frameworks

We have to make it easier for developers to build secure apps, especially Web apps. We can’t keep forcing everybody who builds an application to understand and plug all of the stupid holes in how the Web works on their own – and to do this perfectly right every time. It’s not just wasteful: it’s not possible.

What we need is implementation-level security issues taken care of at the language and framework level. So that developers can focus on their real jobs: solving design problems and writing code that works.

Security Frameworks and Libraries

One option is to get developers to use secure libraries that take care of application security functions like authentication, authorization, data validation and encryption. There are some good, and free, tools out there to help you.

If you’re a Microsoft .NET developer, there’s Microsoft’s Web Protection Library which provides functions and a runtime engine to protect .NET apps from XSS and SQL Injection.

Java developers can go to OWASP for help. As a starting point, someone at OWASP wrote up a summary of available Java security frameworks and libraries.  The most comprehensive, up-to-date choice for Java developers is OWASP’s ESAPI Enterprise Security API especially now that the 2.0 release has just come out. There are some serious people behind ESAPI, and you can get some support from the OWASP forums, or pay Aspect Security to get help in implementing it. ESAPI is big, and as I’ve pointed out before unfortunately it’s not easy to understand or use properly, it’s not nicely packaged, and the documentation is incomplete and out of date – although I know that people are working on this.

Or there’s Apache Shiro (FKA JSecurity and then later as Apache Ki), another secure framework for Java apps. Although it looks simpler to use and understand than ESAPI and covers most of the main security bases (authentication, authorization, session management and encryption), it doesn’t help take care of important functions like input validation and output encoding. And Spring users have Spring Security (Acegi) a comprehensive, but heavyweight authorization and authentication framework.

If you aren’t using ESAPI’s input data validation and output encoding functions to help protect your app from XSS attacks and other injection attacks, you could try OWASP’s Stinger declarative validators (although unfortunately Stinger isn’t an active project any more). Or maybe OWASP’s AntiSamy, an un-cool name for a cool library to sanitize rich HTML input data; or the newer, faster Java HTML Sanitizer built with technology contributed by Google: handy if you’re writing a bulletin board or social network.

Or you could check out the new auto-escaping technology that Jim Manico presented at this year’s SANS AppSec conference including Facebook’s XHP (for PHP programmers), OWASP’s JXT Java XML Templates , Google’s Context-Sensitive Auto-Sanitization (CSAS),and Javascript sandboxing from Google (CAJA – used in the new OWASP HTML Sanitizer) or from OWASP (JSReg).  And JQuery programmers can use Chris Schmid’ts JQuery Encoder to safely escape untrusted data.

To add CSRF protection to your app, try OWASP’s CSRFGuard.  If all you want to do is solve some encryption problems, there’s Jasypt – the Java Simplified Encryption library – and of course The Legion of the Bouncy Castle: a comprehensive encryption library for Java (and C#).

For developers working in other languages like Ruby and PHP and Objective C, there are ports or implementations of ESAPI available, although these aren’t as up-to-date or complete as the Java implementation. Python developers working with the Django framework can check out Django Security a new library from Rohit Sethi at SD Elements.

There are other security frameworks and libraries out there – if you know where to look. If you use this code properly, some or maybe even a lot of your security problems will be taken care of for you. But you need to know that you need it in the first place, then you need to know where to find it, and then you need to figure out how to use it properly, and then test it to make sure that everything works. Fast-moving Agile teams building new apps using simple incremental design approaches or maintenance teams fixing up legacy systems aren’t looking for auto-escaping templating technology or enterprise security frameworks like ESAPI because this stuff isn’t helping them to get code out of the door – and many of them don’t even know that they need something like this in the first place.

Frameworks and Libraries that are Secure

To reach application developers, to reduce risk at scale, we need to build security into the application frameworks and libraries, especially the Web frameworks, that developers already use. Application developers rely on these frameworks to solve a lot of fundamental plumbing problems – and they should be able to rely on these frameworks to solve their problems in a secure way. A good framework should protect developers from SQL Injection and other injection attacks, and provide strong session management including CSRF protection, and auto-escaping protection against XSS. Out of the box. By default.

Ruby on Rails is one example: a general-purpose Web framework that tries to protect developers from CSRF, SQL Injection and now auto-escaping protection against XSS in release 3. Ruby and Rails have security problems but at least the people behind this platform have taken responsible steps to protect developers from making the kind of fundamental and dangerous mistakes that are so common in Web apps.

Solving security problems in frameworks isn’t a new idea. Jeremiah Grossman at Whitehat Security talked about this back in 2006:

The only way I see software security improving significantly is if “security” is baked into the modern development frameworks and be virtually transparent. Remember, the primary developers mission is to pump out code to drive business and that’s what they’ll do not matter what. When developers find that its WAY easier and WAY better to do RIGHT by security, then we’ll get somewhere.

Unfortunately, we haven’t made a lot of progress on this over the last 5 years. A handful of people involved in OWASP’s Developer Outreach are trying to change this, working within some of the framework communities to help make frameworks more secure. It seems hopeless – after all, Java developers alone have dozens of frameworks to choose from for Web apps. But Jim Manico made an important point: to start making a real difference, we don’t need to secure every framework. We just need to make common, important frameworks safer to use, and secure by default: Spring, Struts, Rails, the main PHP and Python frameworks. This will reach a lot of people and protect a lot of software. Hopefully more people will stick with these frameworks because they are feature-rich, AND because they are secure by default. Other teams building other frameworks will respond and build security in, in order to compete. Building safer frameworks could become self-reinforcing as more people get involved and start understanding the problems and solving them. Even if this doesn’t happen, at least developers using some of the more popular frameworks will be protected.

Building secure frameworks and frameworks that are secure isn’t going to solve every application security problem. There are security problems that frameworks can’t take care of. We still need to improve the tools and languages that we use, and the way that we use them, the way that we design and build software. And the frameworks themselves will become targets of attack of course. And we’re all going to have to play catch up. Changing the next release of web application frameworks isn’t going to make a difference to people stuck maintaining code that has already been written. Developers will have to upgrade to take advantage of these new frameworks and learn how to use the new features. But it will go a long way to making the software world safer.

There are only a handful of people engaged in this work so far – most of them on a part-time basis. Such a small group of people, even smart and committed people, aren’t going to be able to change the world. This is important work: I think some of the most important work in application security today. If a government or a major corporation (unfortunately, I don’t work for either) is really looking for a way to help make the Web safer, this it – getting the best and brightest and most dedicated people from the appsec and application development communities to work together and solve foundational problems with wide-reaching impact.

To find out more, or to engaged, join the OWASP Developer Outreach.

Taming the Beast – The Floating Point DoS Vulnerability

Originally posted as Taming the Beast

The recent multi-language numerical parsing DOS bug has been named the “Mark of the Beast“. Some claim that this bug was first reported as early as 2001.This is a significant bug in (at least) PHP and Java. Similar issues have effected Ruby in the past. This bug has left a number of servers, web frameworks and custom web applications vulnerable to easily exploitable Denial of Service.

Oracle has patched this vuln but there are several non-Oracle JVM’s that have yet to release a patch. Tactical patching may be prudent for environment.

Here are three approaches that may help you tame this beast of a bug.

1) ModSecurity Rules

Ryan Barnett deployed a series of ModSecurity rules and documented several options at http://blog.spiderlabs.com/2011/02/java-floating-point-dos-attack-protection.html

2) Java-based Blacklist Filter

Bryan Sullivan from Adobe came up with the following Java-based blacklist filter.

This rule is actually quite accurate in *rejecting input* in the DOSable JVM numeric range. This fix, while simple, does indeed reject a series of normally good values.

[sourcecode language=”java”]
public static boolean containsMagicDoSNumber(String s) {
return s.replace(“.”, “”).contains(“2225073858507201”);
}
[/sourcecode]

3) Double Parsing Code

The following Java “safe” Double parsing code was based on a proof of concept by Brian Chess at HP/Fortify. This approach detects the evil range before trying to call parseDouble and returns the IEEE official value  ( 2.2250738585072014E-308 ) for any double in the dangerous range.
[sourcecode language=”java”]
private static BigDecimal bigBad;
private static BigDecimal smallBad;

static {
BigDecimal one = new BigDecimal(1);
BigDecimal two = new BigDecimal(2);
BigDecimal tiny = one.divide(two.pow(1022));

// 2^(-1022) 2^(-1076)
bigBad = tiny.subtract(one.divide(two.pow(1076)));

//2^(-1022) 2^(-1075)
smallBad = tiny.subtract(one.divide(two.pow(1075)));
}

public static Double parseSafeDouble(String input) throws InvalidParameterException {

if (input == null) throw new InvalidParameterException(“input is null”);

BigDecimal bd;
try {
bd = new BigDecimal(input);
} catch (NumberFormatException e) {
throw new InvalidParameterException(“cant parse number”);
}

if (bd.compareTo(smallBad) >= 0 && bd.compareTo(bigBad) <= 0) {
// if you get here you know you’re looking at a bad value. The final
// value for any double in this range is supposed to be the following safe #
//return safe number
System.out.println(“BAD NUMBER DETECTED – returning 2.2250738585072014E-308”);
return new Double(“2.2250738585072014E-308”);
}

//safe number, return double value
return bd.doubleValue();
}
[/sourcecode]

Top 25 Series – Rank 17 – Integer Overflow Or Wraparound

At first sight, the integer overflow doesn’t look all that serious. Any system has a maximum integer number it is able to represent. For example, this would be 255 for an 8 bit system. Right? (keeping it simple to 8 bits for now) Not always. if the number is a signed integer, the maximum integer represented would be 128. Anything “larger” would become a negative number. The description for CWE 190 [1] got a number of nice examples, and I don’t just want to repeat them here. Let me instead point to a less common, but similar issue I ran into coding in PHP, to illustrate the problem from a different angle.

Like most languages, PHP implements a function to retrieve random numbers. In the PHP case, the function is called “rand” and it takes two argument. One sets the lower end and the other one the higher end of the output range. For example, rand(100,999) will create three digit random numbers.

At some point, I needed some decent random numbers for an ill conceived session implementation. I knew enough at the time to ask PHP for “large” random numbers. So I wrote code that looked a bit like this sample:

<?php
$min=1000000000000;
$max=9999999999999;
for ($b=1;$b<10;$b++) {
print rand($min,$max)."\n";
 }
?>

If you run this code, you will get something like this (yes… this is the output I got from php 5.1.6 right now on my Mac)

841607426
957487601
848768972
958968875
-102310784
-489293383
-337233534
-472732979
105331880

So what happened? These are 9 digits numbers, and they are negative as well as positive!

When I filed a bug report back when, I was essentially told: RTFM! I swallowed my ego and broke down to find the manual and read it [2]. Turns out, that the arguments only work as advertised if they are smaller then “getrandmax”. If you don’t stick within these limits, you essentially end up with an integer wraparound. Depending on the exact parameters you choose, you may actually get numbers that “look ok”, but only the last couple digits change.

Lesson learned: RTFM and be aware of the limitations of your platform!

[1] http://cwe.mitre.org/data/definitions/190.html
[2] http://us2.php.net/rand

What should be part of a PHP Streetfighter API

For my own PHP work, I am using a relatively nimble but effective set of libraries. They have shown to be effective, but are in need of a “redo. ”  I released pieces of it in the past, but none of it is actually terribly useful to the public as it is written for me/by me.

Last week, I received some code that someone wrote for us, which is in bad need of a simple API like that to make it workable (= “secure”).  So I am thinking about about wrapping up a “PHP Streetfighter API”. Here are some initial thoughts:

  • Can’t take more then 24 hrs to write
  • A coder should be able to understand / use it in less then 1 hr
  • should force the coder to use prepared statements, proper input validation and avoid XSS
  • maybe some protection against XSRF
  • maybe some anti-pentesting / honeytoken features

Can this be done? Should I add more to it? Anybody interested in using something like this? This isn’t supposed to replace more complete efforts like the OWASP ESAPI, but instead rather provide something for the myriads of “non enterprise coders” who produce tons of crappy code daily. It also shouldn’t be too hard to “retrofit” an existing application with this API.

What do you think… makes sense? Am I nuts? Want to use it?

Various PHP and MySQL Pitfalls

This is a short post, to summarize some of the issues I see with PHP code and the use of MySQL.  Not too many people know about these pitfalls and they are given rise to some of the more subtle security issues:

1 – “SQL Overflow”

If a value you insert into a column is too large, it is truncated silently. This can lead to security issues if you don’t validate that the submitted string is of the right length.

2 – “Trailing White Space Ambiguity”

Trailing white spaces are removed by MySQL silently. For example, these two queries retrieve the same result:

select role from user where username='Admin';
select role from user where username='Admin   ';   (note the space at the end).

3 – Unbalanced Comments

Older versions of MySQL allow /* to be used unbalanced. For example,

select now() /* test

will work. Newer versions of MySQL require balanced comments (unbalanced was always “illegal” according to the documentation

4 – php ‘rand()’ function returns bad results

If the argument exceeds the maximum integer, you will get not-so random numbers back. This one depends a bit on the version of PHP you are using. But you will not get an error. Instead, you will get negative numbers, or numbers that are not random (e.g. only last couple of digits change).

5 – MySQL “–” comments require a white space

In order to use “–” as a comment, it has to be followed by a whitespace.

select now() –test  will fail
select now() — test will work

You don’t have to use a space. A tab will work just fine and evades some filters.

Got some to add? Use the comments 😉

Session Attacks and PHP – Part 2

Yes, I will talk in this article about why it is not good to leave your session files in /tmp.  But first, allow me to follow Jason’s lead and talk about the session attacks he discussed in Part 2 of his ASP.NET article.  I will keep it short :)

Session fixation isn’t really that much of a problem as long as you stick with a few simple principles.  Remember we called this blog “App Sec Streetfighter“? It’s about simple and reproducible techniques that work while under attack.  So lets keep it simple:

  1. Use only cookies to transport the session token.  This considerably raises the bar on session fixation.  The attacker now has to set a cookie which isn’t easy at all.
  2. Change the session ID whenever the users state changes (logged in vs. logged out).
  3. Change the session ID every so often. (every X pageviews, every X minutes).

In order to change the session id, PHP offers a simple comand, session_regenerate_id, just add it to your header and you will get a new session ID on every page.  If that works for you: great!.   If it causes performance issues, then add some logic to limit the life time of sessions or add the session_regenerate_id whenever the user logs in and out.

One important caveat for session_regenerate_id:  It uses one parameter.  Set it to “true.”  The default is “false,” which will leave the old session intact.

Now to the part everybody appears to be waiting for: Why not /tmp ?

/tmp is a convenient location for session data.  Every Unix system I have seen has a /tmp directory that is globally readable and writable.  But this is just the problem for session data.  The file name itself gives away the session ID.  A listing of all session files will give an attacker a list of all valid sessions. In most dedicated web server scenarios, the risk of leaking /tmp file names is low.  But the defense is simple enough to “just do it” ™:

  • Create a directory which will only hold session data (let’s call it /tmp/phpsessions).
  • This directory should NOT be owned by the apache user, but by root and the apache user’s group.
  • Set permissions to 770.  Sadly, 760 is not possible.  Theoretically, it should work.  PHP (the web server) doesn’t really need to be able to get a list of valid sessions.  But sessions will fail if you set the permissions to 760.

I typically prefer to keep my sessions in a database, less for security reasons but more for scalability.  Memcached sessions is an other great way to get sessions to scale.

Related Articles:

Session Attacks and PHP – Part 1

Session Attacks and ASP.NET – Part 1

Session Attacks and ASP.NET – Part 2

Session Attacks and PHP

This blog is of course inspired by Jason’s ASP .Net blog. I figured as the PHP guy in the group, I may as well cover what he did for .Net from the PHP side.

PHP’s default session mechanism is rather simple and effective. The php.ini file configures how sessions work. Many of the parameters can be overridden within your PHP code, or .htaccess files can be used to create more fine grained configurations for particular directories. The session module is part of PHP by default, but can be disabled at compile time. By default, the session data is saved in files. The directory the session data is stored in is again configured in php.ini and defaults to /tmp (not the best choice, but more about that in a later blog).

Much of the session module can be adjusted, or custom code can be used to store session data in a database.

Like Jason noted for .Net, sessions and authentication are two different things in PHP as well. It is up to the developer to use sessions to store the user’s identifier.

Let’s follow Jason’s outline, and talk about session fixation first!

Session Fixation

PHP provides a number of defenses to prevent session fixation. First of all, the lifetime of a session can be limited in php.ini, or by simply using runtime configuration directives. The one “gotcha” here is that some developers mistake the cookie lifetime for the session lifetime. The session lifetime is the part that counts. It is adjusted via gc_maxlifetime parameters. The “gc” (Garbage Collection) parameters are a bit hard to grasp for someone new to PHP. First of all, it is important to understand that nothing happens in PHP unless a page is rendered. Session data will survive indefinetly if the server is idle. Whenever a page is displayed and a session is initiated, the garbage collection functions run and clean up old session data. There are a total of three parameters that determine how this is done:

gc_probability and gc_divisor: How likely is it that the garbage collection is performed. The probability is calculated as gc_probability/gc_divisor. The default is 1/100, which may be a bit a lot probablility if you only have 100 page views per hour. But if you have 100 page views per second, this is perfectly fine.

gc_maxlifetime: This parameter defaults to 1440 seconds (15 minutes). After 15 minutes of inactivity, the session is considered for garbage collection.

So in short: Using default parameters, the session is deleted within 100 page views after the 15 minute time out expired, assuming that each page view initiates a session.

What does this mean for session fixation and reusing session data: The time window is about 15 minutes by default, which is appropriate for most applications.

PHP does allow for a “referrer check”. Sessions will only be considered if the referrer contains the string defined using the “referer_check” configuration parameter. By default, this parameter is empty. This is a very powerful way to block many session fixation attacks.

It is also rather simple to change the session ID in PHP. session_regenerate_id will create the new session and move the data. Take care to set the optional parameter to “true”. Otherwise, the old session will not be deleted. For the paranoid, it is as easy as adding “session_regenerate_id(true)” to your header file. (and wait for entropy starvation to set in 😉 ).

Now what about the attacker obtaining a valid session id? PHP allows for sessions to be delivered via the URL, or cookies. URL based sessions are disabled by default via the “use_only_cookies” parameter. The cookie itself is configured via php.ini.

Cookies can simply be configured as http_only and secure via php.ini. No need for extra code on this one.

Another item not discussed (yet?) by Jason is the session ID generation. PHP’s session ID generation is reasonably secure by default. It is possible to define the source of the entropy used to create sessions (/dev/random or /dev/urandom), how many bytes of entropy are used and which hash function is used. Plenty of ways to mix it up!

There is a lot more to talk about when it comes to PHP sessions. Let’s see what Jason is up to next! Also note that the facts above are valid for later versions of PHP (5 and later). Maybe I should also write about suhosin one of these days, an excelent PHP hardening module.