Sample code to fix this particular SQL-injection hole - php

Please read fully first
In this answer: How to prevent SQL injection with dynamic tablenames?
Pekka points out why this code:
$clas=$_POST['clas'];
$query="SELECT * FROM $clas ";
Cannot be repaired by using a PDO or mysql-real_escape_string().
Can anyone please provide sample code how to fix this so a newbie can paste that code
(after/adjusting it to his needs) and be safe from SQL-injection.
Please don't explain SQL-injection, I know all about injection and PDO, I just need sample code

You could use a whitelist to ensure that the value is indeed one of the tables you wish to be accessed in that way.
Example:
$allowed_tables = array('table1', 'table2');
$clas = $_POST['clas'];
if (in_array($clas, $allowed_tables)) {
$query = "SELECT * FROM `$clas`";
}
Note that constructing SQL queries directly from GET or POST parameters is usually a bad idea anyways, but a whitelist can make it safe.

You can use the for escape :P
$clas = str_replace('`','\\`',$_POST['clas']);
$query = "SELECT * FROM \`{$clas}\`";
So, is a ver very bad idea.
Do it different.

Related

PHP SQL Injection is it safe?

I want to know if my code is 100% secure agasint SQL injection, it looks like this:
$table = $_GET['table'];
switch ($table) {
case 'data':
$sql = "select * from $table";
break;
case 'anothertable':
$sql = "select * from $table";
break;
}
$con = new mysqli($hostname,$username,$password,$db_name);
$result = $con->query($sql);
If $table is not matched by the switch, you haven't set $sql at all...
Otherwise, you have avoided the risk of injecting bad things via $table by whitelisting the acceptable table names.
One point I would make is that one has to read quite closely to see that $table has changed from an untrusted input to a validated table name. So anyone coming to your code in future may think
that you have a problem here that needs fixing, or
that interpolating variables into SQL queries is generally acceptable.
So probably worth going out of your way to explain in comments what you're doing, and (more importantly) why.
In your place I would avoid such a dynamical querying based on the user input, as it smells of a bad application design,
But in regard of SQL injection your code is safe, as it's rightfully implementing the only proper strategy possible - the whitelisting.
Your code is not safe. Here is an example of how you would make it safe with MySQL (PDO). I'm doing it in PDO because that is what I use often and not mysqli :)
$table = $_GET['table'];
$valid_command = FALSE;//value becomes true if you find your
//value in the following if conditional
if (($table==='table')||($table==='anothertable'))
{
$valid_command = TRUE;
}
if ($valid_command)
{
$sql = "SELECT * FROM table";
$sqlPrepared = $conn->prepare($sql);
$sqlPrepared->bindParam(':table', $table);
$sqlPrepared->execute();
}
If you wish to do this in mysqli, it is easy to adapt it. Hope that helps.

Is this a safe way to prevent sql injections?

I need some opinions about my php coding. I'm specially curious if this is safe against sql injections. Apparently it seems to be, but I might be wrong.
And what do you think of this "style" of coding, as in, is it acceptable or really bad practice ?
$validinputs = array(1,9,21,'a','b');
if(in_array($_GET['search'], $validinputs))
{
$queryfilter = " = " . $_GET['search'];
}
else
{
$queryfilter = "IS NOT NULL";
}
(...)
$query = "SELECT * FROM `table` WHERE `field` {$queryfilter}";
Thanks!
EDIT: In this case i compare with $validinputs because these are the only valid search terms for that field, any other search term would return nothing.
In my opinion, this is acceptable but not good practice at all. Why don't you use the standard SQL escape functions? These are really powerful and maintainable when wrapped in a class. I don't think that someone wants to maintain your application / script when you need to escape your strings this way that often. Probably causing a huge mess.
Ideally, you'd use stored procedures and your query would look like so...
$query = "call find_in_table('" . $_GET['search'] . "')";
... but since you have a list of acceptable inputs and are very strictly filtering them before passing them into a query string, I would say you're quite safe from SQL injection and using a stored procedure would be a performance enhancement for you more so than a security feature.

How i can make my code secure from SQL Injection [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I know i am not secure when i am using this code so anything i can add in my code?
I have tried my self sql injection they are somewhere working but not much as i dont have much knowledge about sql injection. but as hacker are more smart so they can really hack my website.
Url looks like this :
http://example.com/profile.php?userID=1
php
$userID = $_GET['userID'];
$userID = mysql_real_escape_string($userID);
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='$userID'");
$CheckNumber = mysql_num_rows($CheckQuery);
if ($CheckNumber !== 1)
{
header("Location: tos.php");
}
I tried:
http://example.com/profile.php?userID=1'
which hide many things on site.
when i tried
http://example.com/profile.php?userID=1' UNION SELECT * FROM tbl_user; with havij it was hacked
Thanks :|
use mysqli::prepare or at least sprintf
mysql_query(sprintf("SELECT * FROM tbl_user WHERE id='%d'", $userID);
$db = new mysqli(<database connection info here>);
$stmt = $db->prepare("SELECT * FROM tbl_user WHERE id='?'");
$stmt->bind_param("id", $userID);
$stmt->execute();
$stmt->close();
Dont use mysql_* functionality at all.
Use PDO or mysqli.
http://php.net/PDO
http://php.net/mysqli
PDO will escape your data for you.
But for your current code:
$userID = $_GET['userID'];
$userID = mysql_real_escape_string($userID);
if(ctype_digit($userID))
{
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='$userID'");
$CheckNumber = mysql_num_rows($CheckQuery);
if ($CheckNumber !== 1)
{
header("Location: tos.php");
}
} else {
// THE USER ID IS NOT ALL NUMBERS, CREATE AN ERROR
}
I know i am not secure when i am using this code
This statement is wrong.
As a matter of fact, this very code is pretty secure.
And none of the codes you provided below would do any harm. Why do you think it is not secure?
This way is not recommended, yes. And the way you are using to format your queries may lead to injection for some other query. But the present code is perfectly secure.
As long as you are enclosing every variable in quotes and escape special chars in it - it is safe to be put into query.
Only if you omit one these two rules (i.e. escape but don't quote or quote but don't escape) - you are in sure danger. But as long as you're following both, you're safe.
The only reason for "hacking" I can guess of is a single quote used in HTML context. In some circumstances it can "hide many things on the page". But for the SQL, with the code you posted here, it's harmless
Look, out of this link
http://example.com/profile.php?userID=1'
your code will produce such a query
SELECT * FROM tbl_user WHERE id='1\''
which is quite legit for mysql and will even return a record for id=1, as it will cast 1' to 1 and find the record. This is why there is no redirect to tos.php.
So, the problem is somewhere else.
either there is a code that does not follow the rules I posted above
or this problem is unrelated to SQL at all - so, you are barking wrong tree and thus still keep whatever vulnerability open
Most likely you have to echo your values out
u can try type casting the value
<?php
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='".(int)$userID."'");
?>

is this safe in terms of SQL injection?

Currently getting more and more into MySQL. It's something i haven't been too fussed about but i want to write some scripts with it now.
My question is simple, im making a search script and just want to know if my php code can prevent some SQL injections.. the code:
$orig = $_POST['term'];
$term = mysql_real_escape_string($orig);
$sql = mysql_query("select * from db1 where content like '%$term%' ");
Is this ok? Alternatively if anyone has an easier/better/safer way of doing this plese feel inclined to let me know.
To avoid warnings in case $_POST['term'] isn't set:
if (isset($_POST['term'])) {
$term = mysql_real_escape_string($_POST['term']);
$sql = mysql_query("select * from db1 where content like '%$term%' ");
// rest of sql query
}
Yes, it is safe from SQL injection. If you want to use a more systematic method of avoiding SQL injection issues I would recommend learning to use PDO and parameterised queries.
yes it should be fine with mysql_real_escape_string
The standard escaping is often insufficient for values used in the LIKE clause. Unless you want the user to specify % placeholders of his own, you should add:
$term = mysql_real_escape_string($_POST['term']);
$term = addcslashes($term, "%_");
To be precise, this only an issue for very large tables, where excessive %%%% placeholder injection in LIKE queries could decelerate the database server.
In your case mysql_real_escape_string will prevent SQL injection because it escapse single quotes and your string is set between single quotes. So in any case $term will always be just a simple string for SQL.
If you have something like
select * from A where id = $number
then no escaping would prevent an injection like:
0; drop A;
To prevent this scenario you would go well with prepared statements (PDO) or type-checking.

Is this sql query vulnerable to injection?

$column = $_GET['id'];
$result = mysql_query("SELECT $column FROM table");
echo $result;
I'm building a website with mysql and am thus trying to learn about sql injections. I assume that this code is vulnerable, but i cant seem to make a working exploit. How would i pull column 'here' from table 'example2'?
Thanks
Imagine $_GET['id'] was equal to something like this
* FROM anytable_i_want; --
the double hypen means the rest of your string is a comment ... so now the sql you're executing is:
SELECT * FROM anytable_i_want;
The single best way to protect from this kind of nonsense is the prepared statement. If you use, say the PDO interface, you do something like this:
$HANDLE = $PDO->prepare('SELECT ? FROM mytable');
$HANDLE->execute(array($_GET['id']));
now no matter what was submitted as $_GET['id'] it woudlnt have any odd effects.
mysql_real_escape_string will cover you if using my mysql_ family of functions, although there is an exploit in the wild that you may be subject to if you change the charset at runtime.
Take a look at PDO and the use of prepared statements to help with preventing SQL injections:
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
make $column something like :
" here FROM example2 -- "
if the following text was passed as $_GET['id'], you would have an exploit:
$_GET['id'] = '[other sql commands here]';
use either mysql_real_escape_string() or mysqli_real_escape_string() (if you are using the improved interface)

Categories