Ruby security vulnerabilities

Here is the news from the Rails Log:

Drew Yao at Apple uncovered a handful of nasty security vulnerabilities affecting all current versions of Ruby. The details are still under wraps because an attacker can DoS you or possibly execute arbitrary code—holy crap! Better upgrade sooner than later.

According to the official Ruby security advisory, the vulnerable Rubies are:

  • 1.8.4 and earlier
  • 1.8.5-p230 and earlier
  • 1.8.6-p229 and earlier
  • 1.8.7-p21 and earlier

Those of us running Ruby 1.8.4 or earlier must upgrade to 1.8.5 or later for a fix. Those on 1.8.5-7 can grab the latest patchlevel release for a fix.

(Please note: Ruby 1.8.7 breaks backward compatibility and is only compatible with Rails 2.1 and later, so don’t go overboard!)

Automatic security

Security is not easy-to-use, not fancy and it is hard to remember all those nasty attack methods. So there are automatic security checks, firewalls, helpers and a lot more. They are built to make your application more secure. But automatic security tools can’t help you to find logic faults. What if you have a Cross-Site Scripting scanner that checks each and every field in your web application, but with a little knowledge, an attacker could change one id in the URL and he sees his neighbor’s confidential data.

BUT, automatic tools can be of great help, if you won’t solely rely on them. The SafeErb plugin reminds you to sanitize output, but it doesn’t do it automatically. A mass-assignment scanner might find this kind of security holes in you application. Or a web application firewall may protect holes you are not aware of. And, of course, security is a process and should be incorporated into the entire project life cycle.

That having said, I’d like to show you a nice web application firewall for your .htaccess, if you happen to use Apache. It comes from 0x000000.com, a whitehat hacker site, and it’s the result of seven years of server administration. It is not perfect, it is not especially for Rails applications or for your specific application, but it is definitely a good starting point. You can read the tutorial for explanation.

RewriteEngine On
Options +FollowSymLinks
ServerSignature Off

RewriteCond %{REQUEST_METHOD}  ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]RewriteCond %{THE_REQUEST}     ^.*(\\r|\\n|%0A|%0D).* [NC,OR]

RewriteCond %{HTTP_REFERER}    ^(.*)(<|>|’|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]RewriteCond %{HTTP_COOKIE}     ^.*(<|>|’|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]RewriteCond %{REQUEST_URI}     ^/(,|;|:|<|>|”>|”<|/|\\\.\.\\).{0,9999}.* [NC,OR]

RewriteCond %{HTTP_USER_AGENT} ^$ [OR]RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|scan).* [NC,OR]RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|’|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]

RewriteCond %{QUERY_STRING}    ^.*(;|<|>|’|”|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set
|declare|drop|update|md5|benchmark).* [NC,OR]RewriteCond %{QUERY_STRING}    ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR]RewriteCond %{QUERY_STRING}    ^.*\.[A-Za-z0-9].* [NC,OR]RewriteCond %{QUERY_STRING}    ^.*(<|>|’|%0A|%0D|%27|%3C|%3E|%00).* [NC]

RewriteRule ^(.*)$ access_log.php

[Server] Did you update OpenSSL?

Two weeks ago, the Debian package of OpenSSL has been found to generate weak keys (CVE). Here's the news from Heise online:

Security expert Luciano Bello has now discovered a critical vulnerability in the OpenSSL package which makes the random number sequences, and therefore keys generated, predictable. The problem only affects Debian and distributions derived from it, such as Ubuntu and Knoppix. […]

OpenSSL provides connection security for many important network services, such as the Apache web server, the SSH login service, the OpenVPN service, the Bind name server, S/MIME e-mail encryption and the trustworthiness of digital signatures. This could enable attackers to listen in on and manipulate SSL connections, obtain unauthorised access to SSH servers or poison DNS server caches.

As it is a serious security vulnerability, it is strongly advised to update your keys, especially for the SSH login service. Although the security advice is two weeks old already, there are still thousands of servers vulnerable. Heise Security found 5% of nearly 2,000 servers tested to use weak keys.

Real world CSRF: Update your Radiant now

Radiant is a no-fluff, open source content management system designed for small teams, written in Ruby on Rails.

I have found several security problems in Radiant, informed the vendor, who fortunately removed the (critical) vulnerabilities quickly. As an update is available, I’m now publishing information about the vulnerabilites.

CSRF in a real world application
About Cross Site Reference Forgery attacks I’ve written in a previous post. Here is an example of what you can do with it in a real world application: An attacker could add his own administrator users, change the current’s administrator’s user name and password, or create malicious pages in the content management system. Vulnerable is Radiant version 0.6.6 and most likely previous versions. Not vulnerable is version 0.6.7.

In this proof-of-context page, you have to enter the URL of your Radiant setup and click the link. If you you’re still logged in to that site, i.e. your cookie didn’t expire, a new administrator “cracker” with the password “cracker” will be added. Of course the attacker won’t ask you about the URL, and there are many ways to obfuscate the attack.
Changing the password
To change the password of an account, the user doesn’t have to enter the old password. As Radiant version 0.6.7 is not vulnerable to CSRF, the admin’s password may not be changed by CSRF. However, if an attacker manages to use the application in the admin’s name, he will be able to hijack the entire application by changing the admin’s password and possibly the user name. The attacker may use the application if he managed to brute-force the admin’s login credentials or if he got hold of the admin’s cookie (by listening to network traffic, for example).
Although this is an attack with (hopefully) difficult preconditions, I prefer to take care of second level attacks, too. As a precondition, require to enter the old password when changing the password, and use good passwords.
Unsalted passwords
The user’s passwords in the database are encrypted, but not salted. So if someone gets hold of a user entry in the database, he can brute-force the users password in the matter of minutes using rainbow tables. From version 0.6.7, passwords are salted.

 

Holes in the textile
At least the Textile filter is vulnerable to injection, try to inject this:

!http://www.google.com/intl/en_ALL/images/logo.gif(Bunny” onclick=”alert(‘XSS’))!

You can find more details in this post about Textile security. This is how an attacker could introduce malicious content. Of course this would require that the attacker has access to the application. But, as mentioned before, I prefer to make sure less/nothing will happen, if someone got past the first barrier.

The countermeasure against this, is to use Rails’ sanitize() method with the Textile output.

[WebAppSec] Automatic security and HackerSafe

Several people asked me about automatic assessment tools to check the security of an application stack. My opinion is that they may be a great support, but they cannot replace some manual work (oh, well, maybe). Rails test are a great way to make sure your application is safe, but you have to write them on your own. Security is not a plug-n-play product, but rather a process.

Automatic security
One automatic security scan is provided by McAfee. The HackerSafe certification is a service that detects vulnerabilities on web sites using automatic tools. If all tests pass, the site owner gets an HackerSafe logo, that he can put on his site. Over 80,000 sites, according to McAfee, use the HackerSafe logo to increase customer trust. According to the description, the service uses port scans, a vulnerability scan on the network layer, but also an automatic audit of the web application layer. On this layer, it looks for SQL Injection and Cross-Site Scripting (XSS) vulnerabilities. It is, however, not clear whether the service scans for other important attack methods, such as CSRF.

 
XSS and HackerSafe 
But, apparently, protection from XSS and other vulnerabilities is not a prerequisite for the HackerSafe logo. Russ McRee discovered several XSS holes in HackerSafe certified sites which allows the attacker to grab customer credentials or redirect the user to a malicious web site. He also made a video to demonstrate various XSS holes in five certified sites. Someone also found an SQL Injection vulnerability in a HackerSafe certified site. And I've seen at least one HackerSafe site which is vulnerable to CSRF. Although, maybe McAfee does not scan for CSRF, it is definitely an important attack method.
 
McAfee reacts 
A spokesperson for McAfee told British media that the company does not find XSS holes to be as critical as SQL Injection or other vulnerabilities. According to her, an XSS hole would not lead to revocation of the HackerSafe certification, although the company informs the customer about it. She added that XSS holes cannot be exploited to break into a server. No they cannot, but an attacker may steal the user's login credentials or credit card number, install malware on the client's computer or snitch his authentication cookie.
 
HackerSafe – just an image? 
After all, the HackerSafe certificate means that the site is protected against known attacks. It does, however, not mean that the site is not vulnerable to important attacks on the web application layer, which accounts for "an estimated 70% of all security breaches", according to the McAfee web site. And it does not mean that the site has no logic flaws, which gives an attacker (or another user) access to information he is not allowed to see. This can only be done by a manual security audit.

CSRF – An underestimated attack method

Cross Site Reference Forgery works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands.

Most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash stays on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if he can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site of a different domain. Let’s start with an example:

 

  • Bob browses a message board and views a post from an attacker where there is a crafted HTML image element. The element references a command in Bob’s banking application, rather than an image file (note that .src is meant to be src).

  • <img .src=”http://www.bank.com/transfer?account=bob&amount=1000&destination=attacker”>

  • Bob’s session at www.bank.com is still alive, because he didn’t log out a few minutes ago.

  • By viewing the post, the browser finds an image tag, which it tries to load from www.bank.com. As explained before, it will also send along the cookie with the valid session id.

  • The web application at www.bank.com verifies the user information in the corresponding session hash and transfers the money to the attackers account. It then returns a result page which is an unexpected result for the browser, so it will not display the image.

  • Bob doesn’t notice the attack, only a few days later he finds out about the strange transfer.

It is important to notice that the actual crafted image or link doesn’t necessarily has to be situated in the web application’s domain, it can be anywhere – in a forum, blog post or email.

 

See the figure at shiflett.org to see how CSRF works.

 

CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures), less than 0.1% in 2006, but it really is a ‘sleeping giant’ [Grossman]. This is in stark contrast to the results in my (and others) security contract work – CSRF is an important security issue.

 

 

CSRF Countermeasures

First of all, GET and POST have to be used according to the W3C. Secondly, a security token in non-GET requests will protect your application from CSRF.

The HTTP protocol basically provides two main types of requests – GET and POST (and more, but they are not supported by most browsers). The World Wide Web Consortium (W3C) provides a checklist for choosing HTTP GET or POST:

 

Use GET if:

  • The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup).

Use POST if:

  • The interaction is more like an order, or

  • The interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or

  • The user be held accountable for the results of the interaction.

 

The verify method in a controller can make sure that specific actions may not be used over GET. Here is an example to verify that the transfer action will be used over POST, otherwise it redirects to the list action.

 

verify :method => :post, :only => [ :transfer ], :redirect_to => { :action => :list }

 

With this precaution, the attack from above will not work, because the browser sends a GET request for images, which will not be accepted by the web application.

But this was only the first step, because POST requests can be send automatically, too. Here is an example for a link which displays harmless.com as destination in the browser’s status bar. In fact it dynamically creates a new form that sends a POST request (.href is meant to be href).

 

<a .href=”http://www.harmless.com/” onclick=”var f = document.createElement(‘form’); f.style.display = ‘none’; this.parentNode.appendChild
(f); f.method = ‘POST’; f.action = ‘http://www.example.com/account/destroy’; f.submit();return false;”>To the harmless survey</a>

 

Or the attacker places the code into the onmouseover event handler of an image (again, .src is meant to be src):

 

<img .src=”http://www.harmless.com/img” width=”400″ height=”400″ onmouseover=”…” />

 

There are many other possibilities, including Ajax to attack the victim in the background. The solution to this, is to include a security token in non-GET requests, which will be checked on the server-side. In Rails 2 this is a one-liner in the application controller:

 

protect_from_forgery :secret => “123456789012345678901234567890”

 

This will automatically include a security token, calculated of the current session and the server-side secret, in all forms and Ajax requests generated by Rails. You won’t need the secret, if you use CookieStorage as session storage. It will raise an ActionController::InvalidAuthenticityToken error, if the security doesn’t match what was expected.

 

Note that cross-site scripting (XSS) vulnerabilities bypass all CSRF protections. XSS gives the attacker access to all elements on a page, so he can read the CSRF security token from a form or directly submit the form.  This is how the Samy MySpace worm did it.

ImageMagick security advisory

A security advisory has been released for libpng, the "official PNG reference library". Libpng is used by ImageMagick, "a software suite to create, edit, and compose bitmap images". Some Rails applications use it to convert, resize or to create thumbnails. The original security advisory was issued by oCERT:

Applications using libpng that install unknown chunk handlers, or copy unknown chunks, may be vulnerable to a security issue which may result in incorrect output, information leaks, crashes, or arbitrary code execution. The issue involves libpng incorrectly handling zero length chunks which results in uninitialized memory affecting the control flow of the application.

The security advisory from libpng reads:

We believe this is a rare circumstance. It occurs in "pngtest" that is a part of the libpng distribution, in pngcrush, and in recent versions of ImageMagick (6.2.5 through 6.4.0-4). We are not aware of any other vulnerable applications. 

And here is the CVE:

libpng 1.0.6 through 1.0.32, 1.2.0 through 1.2.26, and 1.4.0beta01 through 1.4.0beta19 allows context-dependent attackers to cause a denial of service (crash) and possibly execute arbitrary code via a PNG file with zero length "unknown" chunks, which trigger an access of uninitialized memory.
 
Although the impacts are not clear, it is advisable to update ImageMagick, the current version is 6.4.0-7.

[WebAppSec] The idea of negative CAPTCHAs

Spam and automatic submitters really are a problem. One idea to defend this are CAPTCHAs. CAPTCHAs are noisy images and the user (usually) has to recognize the text in the image and enter it in a field. Although some weak algorithms are already broken, this is a good way to keep junk content away. But as automatic recognition gets better, the CAPTCHAs get more sophisticated, and thus harder to read for humans. CAPTCHAs are annoying.
 
Negative CAPTCHAs
The idea of negative CAPTCHAs is not to ask a user to proof that he's human, but reveal that a spam/login robot is a robot (bot). Most bots are really dumb, they crawl the web and enter their junk in every form's field they can find. Negative CAPTCHAs take advantage of that and include a "honeypot" field in the form which will be hidden from the human user by CSS or JavaScript. Ned Batchelder has several ideas how to do that in his original post.
 
On the server side, you will check the value of the field: If it contains any text, it must be a bot. Then, you can either ignore the post or return a positive result, but not saving the post to the database. This way the bot will be satisfied and moves on. You can do this with annoying users, as well.
 
Next step 
This is the basic idea of negative CAPTCHAs, you can make them more sophisticated with Ned's help.

[WebAppSec] Sign-in seals against phishing

There's a new sign-in seal on the Yahoo! login page, which is intended to make phishing attacks more unlikely.

A sign-in seal is a secret message or photo that Yahoo! will display on this computer only. Look for it every time you sign in to make sure you're on a genuine Yahoo! site. If the message, photo, or colors are different, you may have landed on a phishing site.

There might be other techniques to fight phishing, but it is certainly smart to raise awareness. And the technology behind it is clever too. Of course a normal browser cookie would go away from time to time when you (or the browser) clear your cookie cache. So Yahoo! uses so-called Flash SharedObjects which are sort of Flash cookies. They're available cross-browser, and they won't go away normally, because not many people are aware of how to clear these objects.