holms
holms

Reputation: 9560

cakephp escape function or mysql_real_escape_string is not safe?

Strange problem appeared today on our server. We've got DDOS from % and _ signs in mysql query which were successfully passed through GET request. For example

domain.com/search/%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25v%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25a

it appears to be cakephp doesn't filter them? in official mysql guide they write about this problem a lot. that's how they demonstrate to solve this:

addcslashes(mysql_real_escape_string(“%something_”), “%_”); 

in cakephp framework there's function escape() which used everywhere in models. and look what it contains:

/** 
 * Returns a quoted and escaped string of $data for use in an SQL statement.
 *
 * @param string $data String to be prepared for use in an SQL statement
 * @param string $column The column into which this data will be inserted
 * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
 * @return string Quoted and escaped data
 */ 
    function value($data, $column = null, $safe = false) {
        $parent = parent::value($data, $column, $safe);

        if ($parent != null) {
            return $parent;
        }   
        if ($data === null || (is_array($data) && empty($data))) {
            return 'NULL';
        }   
        if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
            return "''";
        }   
        if (empty($column)) {
            $column = $this->introspectType($data);
        }   

        switch ($column) {
            case 'boolean':
                return $this->boolean((bool)$data);
            break;
            case 'integer' :
            case 'float' :
            case null :
                if ($data === '') {
                    return 'NULL';
                }   
                if (is_float($data)) {                                                                                                               
                    return str_replace(',', '.', strval($data));
                }
                if ((is_int($data) || is_float($data) || $data === '0') || (
                    is_numeric($data) && strpos($data, ',') === false &&
                    $data[0] != '0' && strpos($data, 'e') === false)) {
                        return $data;
                    }
            default:
                $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
            break;
        }   

        return $data;
    }  

just a basic protection agains some variable types and stuff like this.. what about escaping mysql special characters?? about year ago i read how it's possible to escape quote sign with help of percent sign in mysql query =) It was hype of blind injections back then, and that trick worked pretty much everywhere because everybody use mysqli_real_escape_string.

I must state a question here: How to escape variable in cakephp - REALLY SAFELY?

update: some folks in IRC states that REQUEST string must be escaped and not query it self. they probably right, then how can I escape % and _ chars in GET request string without using custom functions.. any sanitize method does it?

Upvotes: 0

Views: 3063

Answers (2)

Dunhamzzz
Dunhamzzz

Reputation: 14798

This doesn't mean Cake is susceptible to SQL injection, as it in the underbelly it uses prepared statements, it does mean you are using a LIKE search query in CakePHP and it's letting the wildcard characters though.

I don't think this is ideal behaviour as I have found this out while developing too, I just have this line above finds that use LIKE now.

$term = str_replace('%', ' ', $term); 

You don't need to take escaping in to your own hands, the framework handles that for you.

Upvotes: 1

JJJ
JJJ

Reputation: 33163

The code example you show is safe. This line:

$data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";

escapes special characters. The method checks for the variable's type - it doesn't need to be escaped if it's not a string.

It would be nice to see a source for the alleged "vulnerability" of mysql_real_escape_string().

Upvotes: 0

Related Questions