11

I'm building a Codeigniter application and I'm trying my hardest to prevent SQL injections. I'm using the Active Record method to construct all my queries. I know Active Record automatically sanitizes the input, but I'm wondering exactly to what extent? Does it simply escape all the quotes, or does it do more? What about preventing obfuscated SQL injections, or other more advanced kinds?

Basically, I'm looking for an in-depth explanation of how CI sanitizes data. Anyone know?

tereško
  • 58,060
  • 25
  • 98
  • 150
Erreth
  • 205
  • 4
  • 16
  • 4
    Have considered looking at the code of CI? – Beat Nov 04 '11 at 23:46
  • Lots of info : http://www.google.com.ng/search?gcx=c&sourceid=chrome&ie=UTF-8&q=codeigniter+sanitize+inputs%3F – Mob Nov 04 '11 at 23:51
  • 1
    PDO Anyone? http://www.php.net/pdo – Bailey Parker Nov 05 '11 at 00:10
  • 1
    CI (at least the version I know) aggressively `sanitizes` (which means: changes!) input (which sucks bad). It does it while initiating the request, before any controller action. Does anyone remember how much we hate `magic_quotes_gpc`? – Rudie Nov 05 '11 at 15:40
  • "Sanitizing" data is totally context dependent. @Rudie: That is a configuration setting that runs CI's `xss_clean()` globally on all `$_REQUEST` data, and it does suck (tampers with the raw data), I don't recommend using it unless you're a total newbie who just needs a security blanket for live applications while you learn how to *properly* handle escaping, validating and processing output. – Wesley Murch Nov 05 '11 at 16:08
  • ...it's nowhere near as bad as magic quotes though. Just make sure to set `$config['global_xss_filtering'] = FALSE;` – Wesley Murch Nov 05 '11 at 16:13

3 Answers3

9

Exactly like this (for the MySQL driver):

  • Tries mysql_real_escape_string() (this will be the case 99% of the time)
  • Falls back to mysql_escape_string()
  • Falls back to addslashes()
  • Manually escapes % and _ in LIKE conditions via str_replace()

https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/drivers/mysql/mysql_driver.php#L294

/**
* Escape String
*
* @access public
* @param string
* @param bool whether or not the string will be used in a LIKE condition
* @return string
*/
function escape_str($str, $like = FALSE)
{
    if (is_array($str))
    {
        foreach ($str as $key => $val)
        {
            $str[$key] = $this->escape_str($val, $like);
        }

        return $str;
    }

    if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
    {
        $str = mysql_real_escape_string($str, $this->conn_id);
    }
    elseif (function_exists('mysql_escape_string'))
    {
        $str = mysql_escape_string($str);
    }
    else
    {
        $str = addslashes($str);
    }

    // escape LIKE condition wildcards
    if ($like === TRUE)
    {
        $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
    }

    return $str;
}

Note that this is merely escaping characters so MySQL queries will not break or do something unexpected, and is used only in the context of a database query to ensure correct syntax based on what you pass to it.

There is no magic that makes all data safe for any context (like HTML, CSV, or XML output), and just in case you were thinking about it: xss_clean() is not a one-size-fits-all solution nor is it 100% bulletproof, sometimes it's actually quite inappropriate. The Active Record class does the query escaping automatically, but for everything else you should be escaping/sanitizing data manually in the correct way for the given context, with your output, not your input.

Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
  • I'm not entirely sure what you mean by sanitizing my output instead of input. I think I understand that if I'm trying to prevent XSS attacks, but what if I'm constructing a mysql query using the active record class? What might that look like? – Erreth Nov 06 '11 at 22:52
  • Whatever you throw at the AR class is ultimately as safe as `mysql_real_escape_string`, with the additional security of `\`escaping\`` table and database names. You shouldn't need to sanitize it for security, only for validity (integer values, maximum length, formatting, etc.). See http://stackoverflow.com/questions/4171115/is-mysql-real-escape-string-enough-to-anti-sql-injection/4171134#4171134, http://stackoverflow.com/questions/5288953/is-mysql-real-escape-string-broken – Wesley Murch Nov 07 '11 at 03:36
3

Active Record only escapes the data, nothing else. SQL injection is prevented by escaping. Then use validation on the forms with their validation class. Should take care of your issues. Here's the link for the other CodeIgniter security items:

CodeIgniter UserGuide Security

Rotimi
  • 4,783
  • 4
  • 18
  • 27
TSquared
  • 95
  • 1
  • 1
  • 4
  • I understand. I'm using the form validation class a little bit, but I guess I should be using it on every form I have. I'll definitely have to do some more aggressive sanitization and validation then. Thanks! – Erreth Nov 06 '11 at 22:50
1

You can always see the latest query made by using the last_query() method.

$this->db->last_query()

You will see exactly how the query looked, so you can verify if sanitized properly.

Rotimi
  • 4,783
  • 4
  • 18
  • 27
Bojan Bjelic
  • 3,522
  • 1
  • 17
  • 18