7/31/2019 Percona SQL Injections
1/78
SQL Injection
Myths and FallaciesBill Karwin, Percona Inc.
7/31/2019 Percona SQL Injections
2/78
7/31/2019 Percona SQL Injections
3/78
www.percona.com
What is SQL Injection?
SELECT * FROM BugsWHERE bug_id = $_GET['bugid']
user input
7/31/2019 Percona SQL Injections
4/78
www.percona.com
What is SQL Injection?
SELECT * FROM BugsWHERE bug_id = 1234 OR TRUE
unintendedlogic
7/31/2019 Percona SQL Injections
5/78
www.percona.com
Worse SQL Injection
UPDATE AccountsSET password = SHA2('$password')WHERE account_id = $account_id
7/31/2019 Percona SQL Injections
6/78
www.percona.com
Worse SQL Injection
UPDATE AccountsSET password = SHA2('xyzzy'), admin=('1')
WHERE account_id = 1234 OR TRUE
changespassword forall accounts
changes accountto administrator
7/31/2019 Percona SQL Injections
7/78www.percona.com
Myths and Fallacies
Based on a grain of truth,but derives a wrong conclusion
Based on a false assumption,
but derives a logical conclusion
MYTH
FALLACY
7/31/2019 Percona SQL Injections
8/78www.percona.com
Myth
SQL Injection is an oldproblem
so I dont have to
worry about it.
MYTH
7/31/2019 Percona SQL Injections
9/78
www.percona.com
Identity Theft
130 million credit card numbers
Albert Gonzalez used SQLInjection to install his packet-sniffer
code onto credit-card serversSentenced 20 years in March 2010
Cost to victim company HeartlandPayment 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
http://www.cio.com/article/492039/Security_Breach_Cost_Heartland_12.6_Million_So_Farhttp://www.cio.com/article/492039/Security_Breach_Cost_Heartland_12.6_Million_So_Farhttp://www.cio.com/article/492039/Security_Breach_Cost_Heartland_12.6_Million_So_Farhttp://www.miamiherald.com/2009/08/22/1198469/from-snitch-to-cyberthief-of-the.htmlhttp://www.miamiherald.com/2009/08/22/1198469/from-snitch-to-cyberthief-of-the.html7/31/2019 Percona SQL Injections
10/78
www.percona.com
Other Recent Cases
(April 2011) Sun.com and MySQL.com attacked by blindSQL Injection attack, revealing portions of the sitesdatabases, including usernames and passwords.
http://techie-buzz.com/tech-news/mysql-com-database-compromised-sql-injection.html
http://seclists.org/fulldisclosure/2011/Mar/309
http://tinkode27.baywords.com/
(April 2011) LizaMoon scareware campaign infectedhundreds of thousands of websites via SQL Injection.
http://www.informationweek.com/news/security/attacks/showArticle.jhtml?articleID=229400764
http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9080580http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9080580http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9080580http://tinkode27.baywords.com/http://tinkode27.baywords.com/http://seclists.org/fulldisclosure/2011/Mar/309http://seclists.org/fulldisclosure/2011/Mar/309http://techie-buzz.com/tech-news/mysql-com-database-compromised-sql-injection.htmlhttp://techie-buzz.com/tech-news/mysql-com-database-compromised-sql-injection.html7/31/2019 Percona SQL Injections
11/78
www.percona.com
2009 Data Breach Investigations Report,Verizon Business RISK Team
When hackers are required to work to gain access,
SQL injection appears to be the uncontestedtechnique of choice. In 2008, this type of attackranked second in prevalence (utilized in 16breaches) and first in the amount of recordscompromised (79 percent of the aggregate 285
million).
http://www.verizonbusiness.com/resources/security/reports/2009_databreach_rp.pdf
Experts Agree
http://www.verizonbusiness.com/resources/security/reports/2009_databreach_rp.pdfhttp://www.verizonbusiness.com/resources/security/reports/2009_databreach_rp.pdfhttp://www.verizonbusiness.com/resources/security/reports/2009_databreach_rp.pdf7/31/2019 Percona SQL Injections
12/78
www.percona.com
Myth
Escaping inputprevents SQL injection.
MYTH
7/31/2019 Percona SQL Injections
13/78
www.percona.com
Escaping & Filtering
UPDATE AccountsSET password = SHA2('xyzzy\'), admin=(\'1')
WHERE account_id = 1234coerced tointeger
backslash escapesspecial characters
7/31/2019 Percona SQL Injections
14/78
www.percona.com
Escaping & Filtering Functions
7/31/2019 Percona SQL Injections
15/78
www.percona.com
Escaping & Filtering Functions
7/31/2019 Percona SQL Injections
16/78
www.percona.com
Identifiers and Keywords
7/31/2019 Percona SQL Injections
17/78
www.percona.com
Myth
If some escaping is good,more must be better.
MYTH
7/31/2019 Percona SQL Injections
18/78
www.percona.com
Overkill?
7/31/2019 Percona SQL Injections
19/78
www.percona.com
FIRE EVERYTHING!!
7/31/2019 Percona SQL Injections
20/78
www.percona.com
Just the One Will Do
7/31/2019 Percona SQL Injections
21/78
www.percona.com
Myth
I can write my ownescaping function.
MYTH
7/31/2019 Percona SQL Injections
22/78
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 insertsbackslash (%5c). Result:
%bf%5c%27 OR 1=1 --
valid multi-bytecharacter in GBK:
single-quote
http://example.org/login.php?account=%bf%27%27OR1=1http://example.org/login.php?account=%bf%27%27OR1=17/31/2019 Percona SQL Injections
23/78
www.percona.com
Grant Access to Any Account
Interpolating:
SELECT * FROM Accounts WHEREaccount = '{$account}' AND password ='{$password}'
Results in:
SELECT * FROM Accounts WHERE
account = '' OR 1=1 -- ' AND password = 'guess'
http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
http://bugs.mysql.com/bug.php?id=8378
http://bugs.mysql.com/bug.php?id=8378http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-stringhttp://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-stringhttp://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-stringhttp://bugs.mysql.com/bug.php?id=8378http://bugs.mysql.com/bug.php?id=8378http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-stringhttp://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string7/31/2019 Percona SQL Injections
24/78
www.percona.com
Solutions
Use driver-provided escaping functions:
mysql_real_escape_string()
mysqli::real_escape_string()
PDO::quote()Use API functions to set the client character set:
mysql_set_charset()
mysqli::set_charset()http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html
Use UTF-8 instead of GBK, SJIS, etc.
Use SQL query parameters (more on this later)
http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.htmlhttp://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html7/31/2019 Percona SQL Injections
25/78
www.percona.com
Myth
Unsafe data comes fromusers
if its already in the
database, then its safe.
MYTH
7/31/2019 Percona SQL Injections
26/78
www.percona.com
Not Necessarily
$sql = "SELECT product_name FROM Products";$prodname = $pdo->query($sql)->fetchColumn();
$sql = "SELECT * FROM BugsWHERE MATCH(summary, description)AGAINST ('{$prodname}')";
not safe input
7/31/2019 Percona SQL Injections
27/78
www.percona.com
Fallacy
Using stored proceduresprevents SQL Injection.
FALLACY
7/31/2019 Percona SQL Injections
28/78
www.percona.com
Static SQL in Procedures
CREATE PROCEDURE FindBugById (IN bugid INT)BEGINSELECT * FROM Bugs WHERE bug_id = bugid;
END
CALL FindByBugId(1234)
filtering by data typeis a good thing
7/31/2019 Percona SQL Injections
29/78
www.percona.com
Dynamic SQL in Procedures
CREATE PROCEDURE BugsOrderBy(IN column_name VARCHAR(100),IN direction VARCHAR(4))
BEGIN
SET @query = CONCAT('SELECT * FROM Bugs ORDER BY ',column_name, ' ', direction);
PREPARE stmt FROM @query;EXECUTE stmt;
END
CALL BugsOrderBy('date_reported', 'DESC')
interpolating arbitrary
strings = SQL injection
7/31/2019 Percona SQL Injections
30/78
www.percona.com
Worthy ofTheDailyWTF
CREATE PROCEDURE QueryAnyTable(IN table_name VARCHAR(100))
BEGINSET @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
http://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspxhttp://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspxhttp://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspxhttp://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspx7/31/2019 Percona SQL Injections
31/78
www.percona.com
Myth
Conservative SQLprivileges limit the
damage.
MYTH
7/31/2019 Percona SQL Injections
32/78
www.percona.com
Denial of Service
SELECT * FROM Bugs JOIN BugsJOIN Bugs JOIN Bugs JOIN Bugs
JOIN Bugs100 bugs = 1 trillion rows
7/31/2019 Percona SQL Injections
33/78
www.percona.com
Denial of Service
SELECT * FROM Bugs JOIN BugsJOIN Bugs JOIN Bugs JOIN Bugs
JOIN BugsORDER BY 1
still requires onlySELECT privilege
7/31/2019 Percona SQL Injections
34/78
www.percona.com
Just Asking for It
http://www.example.com/show.php?query=SELECT%20*%20FROM
%20Bugs
http://www.example.com/show?http://www.example.com/show?7/31/2019 Percona SQL Injections
35/78
www.percona.com
Fallacy
Its just an intranetapplication
it doesnt
need to be secure.
FALLACY
7/31/2019 Percona SQL Injections
36/78
www.percona.com
Just Ask This Manager
7/31/2019 Percona SQL Injections
37/78
www.percona.com
What Stays on the Intranet?
You could be told to give business partners accessto an internal application
UPDATE AccountsSET password =SHA2('$password')WHERE account_id= $account_id
7/31/2019 Percona SQL Injections
38/78
www.percona.com
What Stays on the Intranet?
Your casual code could be copied & pasted intoexternal applications
UPDATE AccountsSET password =SHA2('$password')WHERE account_id= $account_id
UPDATE AccountsSET password =SHA2('$password')WHERE account_id= $account_id
7/31/2019 Percona SQL Injections
39/78
www.percona.com
What Stays on the Intranet?
Its hard to argue for a security review or rewrite fora finished application
$$$
UPDATE AccountsSET password =SHA2('$password')WHERE account_id= $account_id
?
7/31/2019 Percona SQL Injections
40/78
www.percona.com
Myth
My frameworkprevents SQL Injection.
MYTH
7/31/2019 Percona SQL Injections
41/78
www.percona.com
ORMs Allow Custom SQL
Dynamic SQL always risks SQL Injection,for example Rails ActiveRecord:
Bugs.all(:joins => "JOIN Accounts
ON reported_by = account_id",
:order => "date_reported DESC")
any custom SQL cancarry SQL injection
7/31/2019 Percona SQL Injections
42/78
www.percona.com
Whose Responsibility?
Security is the application developers job
No database, connector, or frameworkcan prevent SQL injection all the time
7/31/2019 Percona SQL Injections
43/78
www.percona.com
Fallacy
Query parameters doquoting for you.
FALLACY
7/31/2019 Percona SQL Injections
44/78
www.percona.com
Interpolating Dynamic Values
Query needs a dynamic value:
SELECT * FROM BugsWHERE bug_id = $_GET['bugid']
user input
7/31/2019 Percona SQL Injections
45/78
www.percona.com
Using a Parameter
Query parameter takes the place of a dynamicvalue:
SELECT * FROM Bugs
WHERE bug_id = ?parameterplaceholder
7/31/2019 Percona SQL Injections
46/78
www.percona.com
How the Database Parses It
query
SELECT
FROM
WHERE
expr-list *
simple-table
expr
bugs
parameterplaceholder
?
bug_id
=equality
7/31/2019 Percona SQL Injections
47/78
www.percona.com
How the Database Executes It
query
SELECT
FROM
WHERE
expr-list *
simple-table
expr
bugs
1234
bug_id
=
parametervalue
equality
7/31/2019 Percona SQL Injections
48/78
www.percona.com
Interpolation
query
SELECT
FROM
WHERE
expr-list *
simple-table
expr
1234
bugs
bug_id
=
TRUE
OR
SQL injection
equality
7/31/2019 Percona SQL Injections
49/78
www.percona.com
Parameterization
query
SELECT
FROM
WHERE
expr-list *
simple-table
expr
bugs
1234 OR
TRUE
bug_id
=
no parametercan change the tree
equality
7/31/2019 Percona SQL Injections
50/78
www.percona.com
Sequence of Prepare & ExecuteClient Server
parse query
send parameters
send SQL
optimize query
execute queryreturn results
prepare query
execute query
repeat withdifferentparameters
bind parameters
convert to machine-readable form
7/31/2019 Percona SQL Injections
51/78
www.percona.com
Myth
Query parameters preventSQL Injection.
MYTH
7/31/2019 Percona SQL Injections
52/78
www.percona.com
One Parameter = One Value
SELECT * FROM BugsWHERE bug_id = ?
7/31/2019 Percona SQL Injections
53/78
www.percona.com
Not a List of Values
SELECT * FROM BugsWHERE bug_id IN ( ? )
7/31/2019 Percona SQL Injections
54/78
www.percona.com
Not a Table Name
SELECT * FROM ?
WHERE bug_id = 1234
7/31/2019 Percona SQL Injections
55/78
www.percona.com
Not a Column Name
SELECT * FROM BugsORDER BY ?
7/31/2019 Percona SQL Injections
56/78
www.percona.com
Not an SQL Keyword
SELECT * FROM Bugs
ORDER BY date_reported ?
7/31/2019 Percona SQL Injections
57/78
www.percona.com
Interpolation vs. Parameters
Scenario Example Value Interpolation Parameter
single value 1234 SELECT * FROM BugsWHERE bug_id = $id
SELECT * FROM BugsWHERE bug_id = ?
multiplevalues
1234, 3456, 5678 SELECT * FROM BugsWHERE bug_id IN ($list)
SELECT * FROM BugsWHERE bug_id IN ( ?, ?, ? )
table name Bugs SELECT * FROM $tableWHERE bug_id = 1234
NO
column name date_reported SELECT * FROM BugsORDER BY $column
NO
other syntax DESC SELECT * FROM BugsORDER BYdate_reported $direction
NO
7/31/2019 Percona SQL Injections
58/78
www.percona.com
Solution
Whitelist Maps
SOLUTION
7/31/2019 Percona SQL Injections
59/78
www.percona.com
Example SQL Injection
http://www.example.com/?order=date_reported&dir=ASC
7/31/2019 Percona SQL Injections
60/78
www.percona.com
Fix with a Whitelist Map
7/31/2019 Percona SQL Injections
61/78
www.percona.com
Map User Input to Safe SQL
7/31/2019 Percona SQL Injections
62/78
www.percona.com
Map User Input to Safe SQL
7/31/2019 Percona SQL Injections
63/78
www.percona.com
Interpolate Safe SQL
http://www.example.com/?order=date&dir=up
7/31/2019 Percona SQL Injections
64/78
www.percona.com
Benefits of Whitelist Maps
Protects against SQL injection in cases whereescaping and parameterization doesnt help.
Decouples web interface from database schema.
Uses simple, declarative technique.
Works independently of any framework.
7/31/2019 Percona SQL Injections
65/78
www.percona.com
Fallacy
Queries parameters
hurt SQL performance.
FALLACY
7/31/2019 Percona SQL Injections
66/78
www.percona.com
Simple Query
0
0.001
0.002
0.003
0.004
MySQLMySQLi
MySQLi PrepPDO
PDO Prep
Profiled Elapsed
7/31/2019 Percona SQL Injections
67/78
www.percona.com
Complex Query
0
0.39
0.78
1.17
1.56
MySQLMySQLi
MySQLi PrepPDO
PDO Prep
Profiled Elapsed
7/31/2019 Percona SQL Injections
68/78
www.percona.com
Myth
A proxy/firewall solution
prevents SQL injection.
MYTH
7/31/2019 Percona SQL Injections
69/78
www.percona.com
Oracle Database Firewall
Reverse proxy between application and Oracle
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
7/31/2019 Percona SQL Injections
70/78
www.percona.com
GreenSQL
Reverse proxy for MySQL, PostgreSQL, MicrosoftSQL 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 truehttp://www.greensql.net/about
http://www.greensql.net/abouthttp://www.greensql.net/about7/31/2019 Percona SQL Injections
71/78
www.percona.com
Still not Perfect
Vipin Samar, Oracle vice president of DatabaseSecurity:
Database Firewall is a good first layer of defense fordatabases but it won't protect you from everything,
http://www.databasejournal.com/features/oracle/article.php/3924691/article.htm
GreenSQL Architecture
GreenSQL can sometimes generate false positiveand false negative errors. As a result, some legal
queries may be blocked or the GreenSQL systemmay pass through an illegal query undetected.
http://www.greensql.net/about
http://www.databasejournal.com/features/oracle/article.php/3924691/article.htmhttp://www.databasejournal.com/features/oracle/article.php/3924691/article.htm7/31/2019 Percona SQL Injections
72/78
www.percona.com
Limitations of Proxy Solutions
False sense of security; discourages code review
Gating factor for emergency code deployment
Constrains application from writing dynamic SQL
Doesnt stop SQL injection in Stored Procedures
7/31/2019 Percona SQL Injections
73/78
www.percona.com
Fallacy
NoSQL databases are
immune to SQL injection.
FALLACY
7/31/2019 Percona SQL Injections
74/78
www.percona.com
NoSQL Injection
http://www.example.com?column=password
7/31/2019 Percona SQL Injections
75/78
www.percona.com
NoSQL Injection in the Wild
Diaspora wrote MongoDB map/reduce functionsdynamically from Ruby on Rails:
def self.search(query)Person.all('$where' => "function() {
return this.diaspora_handle.match(/^#{query}/i) ||this.profile.first_name.match(/^#{query}/i) ||this.profile.last_name.match(/^#{query}/i); }")
end
http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/
did query come froma trusted source?
M th d F ll i
http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/7/31/2019 Percona SQL Injections
76/78
www.percona.com
Myths and Fallacies
I dont have to worry anymoreEscaping is the fix
More escaping is better
I can code an escaping function
Only user input is unsafe
Stored procs are the fix
SQL privileges are the fix
My app doesnt need securityFrameworks are the fix
Parameters quote for you
Parameters are the fix
Parameters make queries slow
SQL proxies are the fix
NoSQL databases are the fix
there is no single silver bulletuse all defenses when appropriate
7/31/2019 Percona SQL Injections
77/78
www.percona.com
SQL Antipatterns
http://www.pragprog.com/titles/bksqla/
http://www.pragprog.com/titles/bksqla/sql-antipatternshttp://www.pragprog.com/titles/bksqla/sql-antipatternshttp://www.pragprog.com/titles/bksqla/sql-antipatterns7/31/2019 Percona SQL Injections
78/78
Copyright 2012 Bill Karwinwww.slideshare.net/billkarwin
Released under a Creative Commons 3.0 License:http://creativecommons.org/licenses/by-nc-nd/3.0/
You are free to share - to copy, distribute andtransmit this work, under the following conditions:
Attribution.You must attribute thiswork to Bill Karwin.
Noncommercial.
You may not use this workfor commercial purposes.
No Derivative Works.
You may not alter,transform, or build
upon this work.
http://creativecommons.org/licenses/by-nc-nd/3.0/http://creativecommons.org/licenses/by-nc-nd/3.0/http://www.karwin.com/http://www.karwin.com/Top Related