Percona SQL Injections
Percona SQL Injections
Me
Software developer C, Java, Perl, PHP, Ruby SQL maven MySQL Consultant at Percona Author of SQL Antipatterns: Avoiding the Pitfalls of Database Programming
www.percona.com
www.percona.com
www.percona.com
www.percona.com
www.percona.com
MYTH FALLACY
www.percona.com
MYTH
SQL Injection is an old problemso I dont have to worry about it.
Myth
www.percona.com
Identity Theft
130 million credit card numbers Albert Gonzalez used SQL Injection to install his packet-sniffer code onto credit-card servers Sentenced 20 years in March 2010 Cost to victim company Heartland Payment Systems: $12.6 million
http://www.miamiherald.com/2009/08/22/1198469/from-snitch-to-cyberthief-of-the.html http://www.cio.com/article/492039/Security_Breach_Cost_Heartland_12.6_Million_So_Far
www.percona.com
(April 2011) LizaMoon scareware campaign infected hundreds of thousands of websites via SQL Injection.
http://www.informationweek.com/news/security/attacks/showArticle.jhtml?articleID=229400764
www.percona.com
Experts Agree
2009 Data Breach Investigations Report, Verizon Business RISK Team
When hackers are required to work to gain access, SQL injection appears to be the uncontested technique of choice. In 2008, this type of attack ranked second in prevalence (utilized in 16 breaches) and first in the amount of records compromised (79 percent of the aggregate 285 million).
http://www.verizonbusiness.com/resources/security/reports/2009_databreach_rp.pdf
www.percona.com
MYTH
Escaping input prevents SQL injection.
Myth
www.percona.com
www.percona.com
www.percona.com
www.percona.com
www.percona.com
MYTH
If some escaping is good, more must be better.
Myth
www.percona.com
Overkill?
<?php function sanitize($string){ $string = strip_tags($string); $string = htmlspecialchars($string); $string = trim(rtrim(ltrim($string))); $string = mysql_real_escape_string($string); return $string; } $password = sanitize( $_POST["password"] ); mysql_query("UPDATE Users SET password = '$password' WHERE user_id = $user_id");
real function from a users project
www.percona.com
FIRE EVERYTHING!!
www.percona.com
www.percona.com
MYTH
I can write my own escaping function.
Myth
www.percona.com
Please Dont
addslashes() isnt good enough in a multibyte world Example:
http://example.org/login.php?account=%bf%27 OR 1=1 --
$account = addslashes($_REQUEST(account)); Function sees a single-quote (%27) and inserts backslash (%5c). Result: %bf%5c%27 OR 1=1 -single-quote valid multi-byte character in GBK:
www.percona.com
www.percona.com
Solutions
Use driver-provided escaping functions:
mysql_real_escape_string() mysqli::real_escape_string() PDO::quote()
Use UTF-8 instead of GBK, SJIS, etc. Use SQL query parameters (more on this later)
www.percona.com
MYTH
Unsafe data comes from usersif its already in the database, then its safe.
Myth
www.percona.com
Not Necessarily
$sql = "SELECT product_name FROM Products"; $prodname = $pdo->query($sql)->fetchColumn(); $sql = "SELECT * FROM Bugs WHERE MATCH(summary, description) AGAINST ('{$prodname}')";
not safe input
www.percona.com
FALLACY
Using stored procedures prevents SQL Injection.
Fallacy
www.percona.com
CREATE PROCEDURE FindBugById (IN bugid INT) BEGIN SELECT * FROM Bugs WHERE bug_id = bugid; END CALL FindByBugId(1234)
www.percona.com
www.percona.com
Worthy of TheDailyWTF
CREATE PROCEDURE QueryAnyTable (IN table_name VARCHAR(100)) BEGIN SET @query = CONCAT( 'SELECT * FROM ', table_name); PREPARE stmt FROM @query; EXECUTE stmt; END CALL QueryAnyTable( '(SELECT * FROM ...)' )
http://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspx
www.percona.com
MYTH
Conservative SQL privileges limit the damage.
Myth
www.percona.com
Denial of Service
SELECT * FROM Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs
100 bugs = 1 trillion rows
www.percona.com
Denial of Service
SELECT * FROM Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs JOIN Bugs ORDER BY 1
still requires only SELECT privilege
www.percona.com
www.percona.com
FALLACY
Its just an intranet applicationit doesnt need to be secure.
Fallacy
www.percona.com
www.percona.com
www.percona.com
www.percona.com
$$ $
UPDATE Accounts SET password = SHA2('$password') WHERE account_id = $account_id
www.percona.com
MYTH
My framework prevents SQL Injection.
Myth
www.percona.com
www.percona.com
Whose Responsibility?
Security is the application developers job No database, connector, or framework can prevent SQL injection all the time
www.percona.com
FALLACY
Query parameters do quoting for you.
Fallacy
www.percona.com
www.percona.com
Using a Parameter
Query parameter takes the place of a dynamic value:
www.percona.com
query
FROM
simpletable
bugs bug_id
WHERE
expr
equality
= ?
parameter placeholder
www.percona.com
query
FROM
simpletable
bugs bug_id
WHERE
expr
equality
= 1234
parameter value
www.percona.com
Interpolation
SELECT expr-list * bug_id query FROM simpletable bugs equality = 1234 WHERE expr OR
TRUE
SQL injection
www.percona.com
Parameterization
SELECT expr-list *
query
FROM
simpletable
bugs bug_id
WHERE
expr
equality
= 1234 OR TRUE
www.percona.com
prepare query
execute query send parameters repeat with different parameters return results bind parameters execute query
www.percona.com
MYTH
Query parameters prevent SQL Injection.
Myth
www.percona.com
www.percona.com
www.percona.com
www.percona.com
www.percona.com
www.percona.com
1234
1234, 3456, 5678
SELECT * FROM Bugs SELECT * FROM Bugs WHERE bug_id IN ($list) WHERE bug_id IN ( ?, ?, ? ) SELECT * FROM $table WHERE bug_id = 1234 NO NO
Bugs
column name date_reported SELECT * FROM Bugs ORDER BY $column other syntax DESC
www.percona.com
Solution SOLUTION
Whitelist Maps
www.percona.com
www.percona.com
<?php $sortorders = array("DEFAULT" "status" "date" $directions = array( "DEFAULT" "up" "down" => "bug_id", => "status", => "date_reported" ); => "ASC", => "ASC", => "DESC" );
www.percona.com
www.percona.com
www.percona.com
www.percona.com
Decouples web interface from database schema. Uses simple, declarative technique. Works independently of any framework.
www.percona.com
FALLACY
Queries parameters hurt SQL performance.
Fallacy
www.percona.com
Simple Query
Proled Elapsed
0.004 0.003 0.002 0.001
MySQL MySQLi MySQLi Prep
PDO
0
PDO Prep
www.percona.com
Complex Query
Proled Elapsed
1.56 1.17 0.78 0.39
MySQL MySQLi MySQLi Prep PDO
0
PDO Prep
www.percona.com
MYTH
A proxy/firewall solution prevents SQL injection.
Myth
www.percona.com
Whitelist of known SQL queries Learns legitimate queries from application traffic Blocks unknown SQL queries Also supports Microsoft SQL Server, IBM DB2,
Sybase ASE, SQL Anywhere
http://www.oracle.com/technetwork/database/database-firewall/overview/index.html
www.percona.com
GreenSQL
Reverse proxy for MySQL, PostgreSQL, Microsoft SQL Server Detects / reports / blocks suspicious queries:
Access to sensitive tables Comments inside SQL commands Empty password An or token inside a query An SQL expression that always returns true
http://www.greensql.net/about
www.percona.com
GreenSQL Architecture
GreenSQL can sometimes generate false positive and false negative errors. As a result, some legal queries may be blocked or the GreenSQL system may pass through an illegal query undetected.
http://www.greensql.net/about
www.percona.com
www.percona.com
FALLACY
NoSQL databases are immune to SQL injection.
Fallacy
www.percona.com
NoSQL Injection
http://www.example.com?column=password
<?php $map = new MongoCode("function() { emit(this." . $_GET["column"] . ",1); } "); $data = $db->command( array( "mapreduce" => "Users", "map" => $map ) ); any string-interpolation of untrusted content is Code Injection
www.percona.com
www.percona.com
SQL Antipatterns
http://www.pragprog.com/titles/bksqla/
www.percona.com
Noncommercial. You may not use this work for commercial purposes.
No Derivative Works. You may not alter, transform, or build upon this work.
www.percona.com