Professional Documents
Culture Documents
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 1
SQL Database Security
• SQL-Injection
• SQL and overlong data
• SQL-Transactions / -Errorhandling
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 2
SQL-Injection
• Introduction
• Attack Classification
• Finding SQL-Injection
• Abusing SQL-Injection
• Preventing SQL-Injection
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 3
SQL-Injection (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 4
SQL-Injection (II)
$result = mysql_query($sql);
if (!$result) {
...
}
...
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 5
SQL-Injection (III)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 6
SQL-Injection: Attack-Types (I)
• authentication bypass
• data theft
• denial of service (DOS)
• data manipulation
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 7
SQL-Injection: Attack-Types (II)
• website defacement
• malware distribution
• triggering buffer-overflows in internal SQL functions
• executing shell commands (in MSSQL)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 8
MySQL, PHP and Multi-Query-Processing
• PHP
• disables multi-query-processing by default
• mysqli_multi_query() to use it explicitly
• therefore by default data manipulation only possible in case
of injection into UPDATE, INSERT, REPLACE queries
(or data manipulating stored procedures)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 9
Blackbox Search for SQL-Injection (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 10
Blackbox Search for SQL-Injection (II)
mysql error: You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the
right syntax to use near '' and pass='xxx'' at line 1
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 11
Blackbox Search for SQL-Injection (III)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 12
Abusing SQL-Injections
• Basic injections
• UNION injections
• Blind SQL-injections
• ORDER BY Injections
• information_schema / INTO OUTFILE
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 13
Basic Injections
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 14
UNION Injections (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 15
UNION Injections (II) - Problems
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 16
Blind SQL-Injections
• no direct echo
• data theft through changes in display
• conditional results
• conditional errors
• time delays
• slow, because data is stolen bit by bit
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 17
ORDER BY Injections
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 18
information_schema (I)
• information_schema is a meta-database
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| KEY_COLUMN_USAGE |
| PROFILING |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| STATISTICS |
| TABLES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
+---------------------------------------+
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 19
information_schema (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 20
SELECT ... INTO OUTFILE
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 21
SQL-Injection Prevention
• Input Validation
• Escaping
• Prepared Statements
• Handling Special Cases
• Stored Procedures
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 22
Input Validation
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 23
Escaping
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 24
Escaping-Methods
• Backslash Escaping
\ => \\
‘ => \‘ SELECT * FROM u WHERE name=‘O\‘neil‘
“ => \“
• Duplicating Quotes
‘ => ‘‘
“ => ““ SELECT * FROM u WHERE name=‘O‘‘neil‘
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 25
Escaping-Methods in PHP
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 26
Escaping-Methods in PHP - Example (I)
<?php
$l = mysql_real_escape_string($_GET[‘login‘]);
$p = mysql_real_escape_string($_GET[‘pass‘]);
$result = mysql_query($sql);
if (!$result) {
...
}
...
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 27
Escaping-Methods in PHP - Example (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 28
Escaping Pitfalls - Wrong Usage (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 29
Escaping Pitfalls - Wrong Usage (II)
• Limits
$sql = “SELECT * FROM users LIMIT “. escapeFunc($limit);
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 30
Escaping Pitfalls - Late Modification (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 31
Escaping Pitfalls - Late Modification (II)
• Example: Length-Trimming
<?php
$l = mysql_real_escape_string($_GET[‘login‘]);
$l = substring($l, 0, 8);
?>
aus 1234567‘
wird 1234567\‘
und dann 1234567\
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 32
Escaping Pitfalls - Encoding (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 33
Escaping Pitfalls - Encoding (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 34
Escaping Pitfalls - Encoding (III)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 35
Escaping Pitfalls - Encoding (IV)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 36
Escaping Pitfalls - Encoding Changes
• mysql(i)_set_charset(“gbk“);
• pro: changes encoding in a way that allows libmysql to
notice the change
• contra: requires PHP >= 5.2.3
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 37
Prepared Statements (I)
• Escaping
• is complicated
• is prone to errors
• doesn‘t solve the real problem - „mixture of data and control
stream“
• Prepared Statements
• originally meant for optimizing performance
• solve the mixture-problem
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 38
Prepared Statements (II)
➡ mixture-problem is solved
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 39
Prepared Statements (III)
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 40
Prepared Statement Pitfalls
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 41
Handling Special Cases (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 42
Handling Special Cases (II)
<?php
$sortColumn = $_GET[‘sort‘];
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 43
Handling Special Cases (III)
• Limits
• values must be numbers
• Sort-direction
• Whitelist - only ASC and DESC are allowed
<?php
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 44
Handling Special Cases (IV)
function escapeFunc($val)
{
if (is_int($val)) return $val;
return “‘“ . mysql_real_escape_string($val) . “‘“;
}
function buildIN($arr)
{
array_walk($arr, ‘escapeFunc‘);
return ‘ IN (‘ . implode(‘, ‘, $arr) . ‘)‘;
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 45
Handling Special Cases (V)
function buildIN($arr)
{
array_walk($arr, ‘escapeFunc‘);
return ‘ IN (?‘ . str_repeat(‘, ?‘, count($arr)-1)) . ‘)‘;
}
?>
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 46
Stored Procedures (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 47
Stored Procedures (II) - Example
DELIMITER $$
DROP PROCEDURE IF EXISTS getUserId$$
CREATE PROCEDURE getUserId (
IN in_login varchar(20),
IN in_pass varchar(20),
OUT out_id int)
BEGIN
SELECT id INTO out_id
FROM users
WHERE name=in_login AND pass=in_pass;
END$$
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 48
Stored Procedures (III) - Example
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 49
SQL and overlong Data
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 50
Overlong Daten - max_allowed_packet
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 51
Overlong Data - Columnsize (I)
• wird ‘admin ‘
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 52
Overlong Data - Columnsize (II)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 53
Overlong Data - Countermeasures
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 54
Errorhandling (I)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 55
Errorhandling (II)
• or faulty database
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 56
Errorhandling (III)
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 57
Questions ?
Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 • June 2009 • 58