2

Possible Duplicate:
Best way to prevent SQL Injection in PHP

I just found that my website is vunerable.

Since it's connected to a DB and have functions like: Register, Change Password, Notices, etc... and SUPOSING it's fully vulnerable.

What should I look for into the code in order to start making it safe?

I mean, I did some researches and everywhere, everyone says different things about security.

"Use PDO."

"Use mysql_real_escape_string."

"Use addslashes."

What exactly should I look for??

"$_POST" and "$_GET" variables??
"$_SESSION" variables?

SQL querys?

$sql = "select * from user";
$sql = "update user set user="new_user_name";
$sql = "insert into user (user) values ('userid')";

What should I do in each case? Please, help me to know what and where I must go.

Thank you.

Community
  • 1
  • 1
Genesis
  • 1,307
  • 2
  • 13
  • 21
  • 6
    Before you can secure yourself, you need to know the reasons why. Try http://bobby-tables.com (silly name, serious topic) – Marc B Aug 07 '12 at 05:03

4 Answers4

5

Following are the points to be considered for making safe php application.

  1. USE PDO or mysqli
  2. Never trust any inputs. Consider every variable viz $_POST, $_GET, $_COOKIE, $_SESSION, $_SERVER as if they were tainted. Use appropriate filtering measure for these variables.
  3. To avoid XSS attack use php’s builtin functions htmlentities, strip_tags, etc while inserting the user input data into the database.
  4. Disable Register Globals in PHP.INI
  5. Disable “allow_url_fopen” in PHP.INI
  6. Don’t allow user to input more data than required. Validate input to allow max number of characters. Also validate each field for relevant datatypes.
  7. Disable error reporting after Development period. It might give information about database that’ll be useful to hackers.
  8. Use one time token while posting a form. If token exist and matches the form post is valid otherwise invalid.
  9. Use parametrized database queries
  10. Use stored procedures

You can google for each point for more details. HOpe this helps

WatsMyName
  • 4,240
  • 5
  • 42
  • 73
1

What you should look for: Any data send from the client/user. Sanitize/escape this data.

PDO can sanitize queries (using PDO::prepare) and supports multiple SQL systems.

For MySQL, use MySQLi. mysqli_real_escape_string is the function to use for sanitizing data if you are using MySQL.

uınbɐɥs
  • 7,236
  • 5
  • 26
  • 42
  • 2
    -1 for suggesting that PDO somehow automagically sanitizes queries. – Vatev Aug 07 '12 at 05:08
  • Oops... I should have said 'PDO can sanitize database queries'. Edited my answer. Thanks for mentioning that @Vatev! – uınbɐɥs Aug 07 '12 at 05:36
  • 1
    What you meant is 'PDO automatically escapes parameter strings (but only parameters, not if you concatenate them in query string)' – Imre L Aug 07 '12 at 06:59
1

None of the SQL queries you provided are actually vulnerable to SQL injection.

SQL injection vulnerabilities happen because SQL input is not properly escaped.

For example:

$sql = "select * from users where user_id ="  . $_GET['user_id'];

Consider if I passed in the following:

http://some_server.com/some_page.php?user_id=123%20or%201=1

The query when executed would end up being:

select * from users where user_id = 123 or 1=1

To fix this, use parameterized queries:

$query = "select * from users where user_id = ?"

When you bind the user_id value to the query, the data access layer will escape the input string properly and the following would be executed:

select * from users where user_id = '123 or 1=1' which would not return any rows, preventing the injection

If using PHP and the mysql extension:

$sql = "select * from users where user_id = '" . mysql_real_escape_string($_GET['user_id']) . "'";

Keep in mind you need to escape ALL input that is going into a SQL query:

$sql = "select id_column from some_table where id = 1";
$stmt = mysqli_query($conn, $sql);
if($stmt === false) die(mysqli_error($conn) . "\n");
while($row = mysqli_fetch_assoc($conn, $stmt) {
    $sql = "update some_other_table set some_value = 'new value' where some_column = '" . mysqli_real_escape_string($conn, $row['id_column']) . "'";
    ....
}

This is because values you select from the database might include characters that are not safe for execution in a SQL statement, like the name "O'Hara" or example. }

Justin Swanhart
  • 1,826
  • 13
  • 15
  • for simplicity I used the mysql() extension. Applies equally to PDO or mysqli extentions. If using PDO, then make sure you are using prepared statements. MySQLi can use prepared statements or mysqli::real_escape_string. – Justin Swanhart Aug 07 '12 at 05:38
  • Why didn't you use `mysqli` in your example? People finding this from a search might copy and paste code. – uınbɐɥs Aug 07 '12 at 05:41
  • I like the mysql extension. All my code still uses it, so I use it naturally. In recent versions of PHP mysql, mysqli and PDO all use the mysqlnd driver, so in reality there aren't differences between the different extensions. – Justin Swanhart Aug 07 '12 at 05:45
  • The use of `mysqli_*` functions **is discouraged**. See [this](http://news.php.net/php.internals/53799) and [`mysql_query`](http://php.net/manual/en/function.mysql-query.php). Please, *use MySQLi*. [Here is an article on choosing an API](http://php.net/manual/en/mysqlinfo.api.choosing.php). – uınbɐɥs Aug 07 '12 at 05:53
  • If you want to use mysqli use mysqli. Just because mysql extension is "discouraged" (ie deprecated) doesn't mean it doesn't work as a simple example. Feel free to edit my answer if you want to change the extension. – Justin Swanhart Aug 07 '12 at 06:04
  • I've never used mysqli or PDO. My applications are old and still use the mysql extension, so I honestly don't know PDO or mysqli well enough to give accurate meaningful examples for those extensions. You can apply the same concepts with mysql extension to mysqli. Sorry if this isn't helpful. – Justin Swanhart Aug 07 '12 at 06:13
  • To make a most basic switch from `mysql` to `mysqli`, just assign a variable to the connection (e.g. `$conn = mysqli_connect(...);`) and use that variable when using any other MySQL function (e.g. `mysqli_query($conn, ...);`). Your example can quite easily be converted to MySQLi (which I just did in an edit). – uınbɐɥs Aug 07 '12 at 06:43
0

I've been using PDO.

An example for that in your case:

<?php
   $stmt = $dbh->prepare("insert into user (user) values (?)");
   $stmt->bindParam(1, $name);
   $name = 'ValueHere';
   $stmt->execute();
?>
John Woo
  • 258,903
  • 69
  • 498
  • 492