This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

Difference between revisions of "CRV2 SQLInjPHP"

From OWASP
Jump to: navigation, search
 
(11 intermediate revisions by the same user not shown)
Line 11: Line 11:
 
SQL Injection in PHP remains the number one attack vector, and also the number on reason for DATA COMPROMISES  
 
SQL Injection in PHP remains the number one attack vector, and also the number on reason for DATA COMPROMISES  
  
==Data Validation==
+
==Data Validation and prepared statements==
All external input to the system should undergo input validation. The validation rules are defined by the business requirements for the application. If possible, an exact match validator should be implemented. Exact match only permits data that conforms to an expected value. A "Known good" approach (white-list), which is a little weaker, but more flexible, is common. Known good only permits characters/ASCII ranges defined within a white-list. Such a range is defined by the business requirements of the input field. The other approaches to data validation are "known bad," which is a black list of "bad characters". This approach is not future proof and would need maintenance. "Encode bad" would be very weak, as it would simply encode characters considered "bad" to a format which should not affect the functionality of the application.
+
It is as simple as this the absence of data validation and prepared statements or stored procedures will increase the possibility that your code contain SQL injections.
 +
If your application gives the users the possibility to change parameters and those parameters are not verified and inserted
 +
in an unprepared statement than your code contain an SQL Injection.
  
==Business Validation==
+
Example 1 :
Business validation is concerned with business logic. An understanding of the business logic is required prior to reviewing the code which performs such logic. Business validation could be used to limit the value range or a transaction inputted by a user or reject input which does not make too much business sense. Reviewing code for business validation can also include rounding errors or floating point issues which may give rise to issues such as integer overflows which can dramatically damage the bottom line.  
+
<?php
 +
$pass=$_GET["pass"];
 +
$con = mysql_connect('localhost', 'owasp', 'abc123');
 +
mysql_select_db("owasp_php", $con);
 +
$sql="SELECT card FROM users WHERE password = '".$pass."'";
 +
$result = mysql_query($sql);
 +
?>
  
==Canonicalization==
+
==Suspicious Validation==
Canonicalization is the process by which various equivalent forms of a name can be resolved to a single standard name, or the "canonical" name.  
+
The most common ways to prevent SQL Injection in PHP are using functions such as addslashes() and mysql_real_escape_string()
 +
but those function can always cause SQL Injections in some cases.
  
The most popular encodings are UTF-8, UTF-16, and so on (which are described in detail in RFC 2279). A single character, such as a period/full-stop (.), may be represented in many different ways: ASCII 2E, Unicode C0 AE, and many others.
+
'''addslashes :'''
  
With the myriad ways of encoding user input, a web application's filters can be easily circumvented if they're not carefully built.  
+
you will avoid Sql injection using addslashes() only in the case when you wrap the query string with quotes.The following example would still be vulnerable 
 +
<?php
 +
 +
$id = addslashes( $_GET['id'] );
 +
$query = 'SELECT title FROM books WHERE id = ' . $id;
 +
 +
?>
  
==Bad Example==
 
public static void main(String[] args) {
 
    File x = new File("/cmd/" + args[1]);
 
    String absPath = x.getAbsolutePath();
 
}
 
  
==Good Example==
+
'''mysql_real_escape_string():'''
public static void main(String[] args) throws IOException {
 
    File x = new File("/cmd/" + args[1]);
 
    String canonicalPath = x.getCanonicalPath();
 
}
 
  
 +
mysql_real_escape_string() is a little bit more powerful than addslashes() as it calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
 +
As with addslashes(), mysql_real_escape_string() will only work if the query string is wrapped in quotes. A string such as the following would still be vulnerable to an SQL injection:
  
==References==
+
<?php
'''See Reviewing code for Data Validation (in this guide)'''
+
[[Reviewing_Code_for_Data_Validation|Reviewing code for Data Validation]]
+
$bid = mysql_real_escape_string( $_GET['id'] );
 +
$query = 'SELECT title FROM books WHERE id = ' . $bid;
 +
 +
?>
 +
 
 +
==Recommendation==
 +
the formula for Sql-injection-free code:
 +
Good Data Validation + Prepared Statement
  
 +
The PHP Data Objects (PDO) extension defines an abstract database interface that offers parameterized queries for prepared statements and stored procedures. It is available from PHP 5. Use of PDO::prepare will provide good SQL injection defenses, with some exceptions
  
'''See the OWASP ESAPI Project'''
+
Example:
 +
<?php
 +
$id = htmlspecialchars($_GET["id"]); //Validation
 +
$sql = 'SELECT * FROM users WHERE id = :calories';
 +
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); //prepared statement
 +
$sth->execute(array(':id' => $id));
 +
$red = $sth->fetchAll();
 +
?>
  
The [[ESAPI|OWASP ESAPI]] project provides a reference implementation of a security API which can assist in providing security controls to an application.
+
==References==
 +
[http://www.php.net/manual/en/book.pdo.php PDO]
  
 
{{LinkBar
 
{{LinkBar

Latest revision as of 18:35, 5 April 2014

««Reviewing code for SQL Injection«« Main
(Table of Contents)
»»CRV2 SQL Injection Java»»

Introduction

An SQL injection Attack consists of injecting sql query portions in the back-end database system via the client interface in the web application. The consequence of a successful exploitation of an SQL injection varies from just reading data to modifying data or executing system commands. SQL Injection in PHP remains the number one attack vector, and also the number on reason for DATA COMPROMISES

Data Validation and prepared statements

It is as simple as this the absence of data validation and prepared statements or stored procedures will increase the possibility that your code contain SQL injections. If your application gives the users the possibility to change parameters and those parameters are not verified and inserted in an unprepared statement than your code contain an SQL Injection.

Example 1 :

<?php
$pass=$_GET["pass"];
$con = mysql_connect('localhost', 'owasp', 'abc123');
mysql_select_db("owasp_php", $con);
$sql="SELECT card FROM users WHERE password = '".$pass."'";
$result = mysql_query($sql);
?>

Suspicious Validation

The most common ways to prevent SQL Injection in PHP are using functions such as addslashes() and mysql_real_escape_string() but those function can always cause SQL Injections in some cases.

addslashes :

you will avoid Sql injection using addslashes() only in the case when you wrap the query string with quotes.The following example would still be vulnerable

<?php

$id = addslashes( $_GET['id'] );
$query = 'SELECT title FROM books WHERE id = ' . $id;

?>


mysql_real_escape_string():

mysql_real_escape_string() is a little bit more powerful than addslashes() as it calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a. As with addslashes(), mysql_real_escape_string() will only work if the query string is wrapped in quotes. A string such as the following would still be vulnerable to an SQL injection:

<?php

$bid = mysql_real_escape_string( $_GET['id'] );
$query = 'SELECT title FROM books WHERE id = ' . $bid;

?>

Recommendation

the formula for Sql-injection-free code:

Good Data Validation + Prepared Statement

The PHP Data Objects (PDO) extension defines an abstract database interface that offers parameterized queries for prepared statements and stored procedures. It is available from PHP 5. Use of PDO::prepare will provide good SQL injection defenses, with some exceptions

Example:

<?php
$id = htmlspecialchars($_GET["id"]); //Validation
$sql = 'SELECT * FROM users WHERE id = :calories';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); //prepared statement
$sth->execute(array(':id' => $id));
$red = $sth->fetchAll();
?>

References

PDO


««Session Management«« Main
(Table of Contents)
»»Error Handling»»