Does sanitizing input data prevent sql injection? [duplicate] - php

This question already has answers here:
How to use prepare() with dynamic column names?
(2 answers)
How can I prevent SQL injection with dynamic tablenames?
(3 answers)
Closed 4 years ago.
Well, table and column names cannot be replaced by parameters in PDO. As a requirement, mentioning static column name is not possible here. So, I use santize. Is it enough to prevent sql injection like bind param method. What can be best method ?
$id = filter_var($_POST['id'], FILTER_SANITIZE_STRING);
$text = filter_var($_POST['text'], FILTER_SANITIZE_STRING);
$column_name = filter_var($_POST['column_name'], FILTER_SANITIZE_STRING);
$result = $con->query("UPDATE menu SET $column_name='$text' WHERE mid=$id") OR die($con->error);

You can sanitise a value for syntax, you cannot sanitise it for meaning. SQL-injection by its definition means that you make the query do something different than was intended. Here you are leaving your query wide open for anyone to substitute column names, which are essential to the query structure. By allowing users to change columns, you don't have control over what columns may get changed in the query, which is by definition a form of SQL injection.
You need a whitelist of column names users are allowed to change. If a user is allowed to change any column (even the primary id…!?), and you don't feel like keeping a list of column names in an array, then you can query your database for the names of columns in the targeted table and use that as whitelist.

Related

Can we use variable value in direct query using OOPS concept ? - SQL Injection [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 5 days ago.
I am creating a website using PHP PDO oops concept. For like - I want to count columns for different columns. I have created a function in a class. I follow all steps to secure data (SQL injection).
My function -
public function count_by_id($table,$col,$val)
{
$table=$this->sanitize($table,'string');
$col=$this->sanitize($col,'string');
$val=$this->sanitize($val,'string');
$sql= "SELECT count(*) FROM $table WHERE $col=:val";
$stmt = $this->dbConnection->prepare($sql);
$stmt->bindParam(':val', $val, PDO::PARAM_STR);
$stmt->execute();
$number_of_rows = $stmt->fetchColumn();
return $number_of_rows;
}
$table is a static variable that will not change any value. I use it only for table name and also the same for column name. The table and col values will not be changed by the end user. The end user will change only $val value and I have bound that value using a prepared statement.
Like - Calling a function -
count_by_id('users','username',$username);
The users and username will not change but $username will change and I have bound it. Is there any reason for SQL injection or not? I am not getting the table name and column name from the form.
I can use it for different table and column like this-
count_by_id('posts','slug',$slug);
I am totally confused because many programmers are doing like me and many say this may be the reason for SQL injection.
What is your view on that ?

"SELECT :parameter FROM .." in PDO [duplicate]

This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 8 years ago.
I'm trying to select a variable column name in my table, but this doesn't seem to work:
$reponse = $bdd->prepare('SELECT :day AS day FROM TABLE WHERE id= :id');
$reponse->execute(array('day' => 'monday', 'id' => '5'));
$day = $reponse->fetch();
Even by setting 'day', to a sure known element in my table (monday), it doesn't work. Same for id.
Does someone know how to fix that?
I have no php error output, only a mysql query error (that doesn't show).
By replacing ':day' by monday, I have an output.
Due to the order in which the SQL is parsed, there's simply no way to use a bound parameter as part of the SQL statement (for example, a column or table name).
Instead, you'll need to build the string with string concatenation. If the value of :day comes from an external source (database, POST parameter, etc), to avoid possible SQL injection attacks you'll want to validate the input to make sure it's a valid column or expression.
Table and Column names cannot be replaced by parameters in PDO. You will need to filter and sanitize the data manually.

Query works in phpmyadmin but not in PHP [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
Ok so i have this kind of query
SELECT * FROM table WHERE column LIKE 'Blahblahblah Blah - Blah (Blah-Blah)'
(Yep, column values are 20-30 characters long)
And it works in phpmyadmin and returns ~ 100 results.
But whn i try it in PHP framework CI (CodeIgniter)
It is not returning any values.
My code looks like:
$sql = "SELECT * FROM table WHERE column LIKE '$val' ORDER BY column ASC";
$sql = $this->db->query($sql);
return $sql->result();
So how do i get this to work?
Before you try to make it work, you really, really need to change the way you're constructing the query. You should use a prepared statement where you introduce variables, and then bind them to values.
The way you've written it is horribly vulnerable to SQL injection attacks. (Suppose $val contained '; DROP DATABASE blah; .... What would the whole SQL statement now look like?) If you try to solve the problem in its current form, you'll end up with something that works but will be very dangerous. Make it safe first with a prepared statement.
Details in this linked question.

How to Perform SQL Injection making a SELECT statement UPDATE or INSERT rows? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MySQL Injection - Use SELECT query to UPDATE/DELETE
So I have found in my site bug that allows to perform sql injection
http://mysite.com/script.php?id=1 union select 1,2,3 will output all fields that has Id property equal to one plus one additional row with 1,2,3. I know that I have to validate user input to close my bug.
However my question is quite another. Is it possible to perform update query or insert query? I am able to comment query using --, however I cannot use multiple statements that are delimited by ;. So is it possible to perform update query in my case. I can show PHP code and SQL query if needed.
$sql = "SELECT id, title, text from table where cId=$val";
$result = mysql_query($sql);
$array = mysql_fetch_array($result);
//echo rows in table
Judging from MySQL Injection - Use SELECT query to UPDATE/DELETE
all that is protecting you is a limitation of mysql_query. I would not rely on this, and in particular not that it remains this way over time. You should never rely on a feature to be disabled by default. Maybe the next version already allows statements such as.
SELECT id, title, text from table where cId=1; DROP table table
Nope it is not possible. Most probably you ar running mysql_query, that would not allow multiple queries to be run in one pass. And hence if your query starts with SELECT (as it does), it would not allow any UPDATE injection
Edit: Use mysql_real_escape_string on your input even then
By default this should not be possible. Although there are options for mysql_query to run multiple statements in one string since MySQL 5.0 which you have to set with mysql_set_server_option.
Please consider changing your statement command like this to use mysql_real_escape_string:
$q = mysql_fetch_array(mysql_query("SELECT id, title, text from table where cId = " . mysql_real_escape_string($val)));
At the very best you change your code to use PDO since all mysql_* functions are officially deprecated.

recommended way to safely use a user specificed order by in a SQL statement

Is it posible to bindParam in the order by portion of a sql statement.
For example, is the following possible?
select whatever from table where age > :age order by :user_specified_order_by_field_name_here
and if not, what's the recommended way to make sure that the user_specified_order_by_field_name_here does not contain SQL injection code?
No, PDO doesn't support dynamic table or column names as prepared values. Any column names you insert into the query will not be escaped, and will lead to a SQL injection vulnerability.
PDO::Quote() won't help either - it can escape strings only, but in mySQL, column names aren't strings.
The only 100% safe way to prevent problems is to compare user_specified_order_by_field_name_here against a list of valid columns in the table. You could even use numbers (that you resolve into column names internally) to add an additional layer of obscurity.

Categories