This question already has answers here:
SQL injection that gets around mysql_real_escape_string()
(4 answers)
Closed 5 years ago.
So I know that using prepared statements with placeholders is pretty much the only way to protect yourself from SQL injection due to poor formatting of your queries. However, I also see many people suggesting that, although mysqli_real_escape_string is NOT safe, using it with single quotes around the variable is. For example (note the single quotes in the query):
$value1 = mysqli_real_escape_string($value1);
$value2 = mysqli_real_escape_string($value2);
$value3 = mysqli_real_escape_string($value3);
mysqli_query("INSERT INTO table (column1, column2, column3)
VALUES ('" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";
So: when only dealing with integers and strings, would the above example be just as safe as if you were to use mysqli prepared statements and placeholders?
It is not mysqli_real_escape_string that is not safe, but the way PHP users tend to use it.
As long as you are setting a character set with set_charset() and always wrapping your escaped values in single quotes, despite the type, then technically the statement above would be safe.
However, as you can see, there are too much rules to follow - a condition that is too complex for an average PHP user. Therefore, this kind of manual formatting is an endless source of injections, simply because any rule (escaping, quoting, setting a charset) could be just forgotten to apply.
Besides, manual escaping just makes your code bloated. Why not to let a program to process your data properly for you?
This is why you have to have a mechanism to apply all the rules automatically. So prepared statements is such a mechanism.
What's wrong with a simple function like this, any reason you want to prefer your code to it:
$sql = "INSERT INTO table (column1, column2, column3) VALUES (?,?,?)";
some_query($sql, [$value1,$value2,$value3]);
Related
$tablename = "channel";
mysql_query("INSERT INTO '".$tablename."' (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')");
In PHP a double quoted string literal will expand scalar variables. So that can be done like this
$sql = "INSERT INTO $tablename (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')";
I assume you thought that the single quotes were requred around the table name, they are not in fact they are syntactically incorrect.
You may wrap the table name and the columns names in backtick like this
$sql = "INSERT INTO `$tablename` (`episode_name`,`episode_title`,`episode_date`)
values ('$videoname','$videotitle','$date')";
The reason that the Values(....) are wrapped in single quotes is to tell MYSQL that these are text values, so that is not only legal syntax but required syntax if the columns are defined as TEXT/CHAR/VARCHAR datatypes
However I must warn you that
the mysql_ database extension, it
is deprecated (gone for ever in PHP7) Specially if you are just learning PHP, spend your energies learning the PDO database extensions.
Start here its really pretty easy
And
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
Use prepared statement and parameterized statements
Dont use quotes arround table name or use backtick
mysql_query("INSERT INTO $tablename (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')");
"INSERT INTO `$tablename` (episode_name,episode_title,episode_date) values ('$videoname','$videotitle','$date')";
OR
"INSERT INTO `".$tablename."` (episode_name,episode_title,episode_date) values ('$videoname','$videotitle','$date')";
This question already has answers here:
Escaping single quote in PHP when inserting into MySQL [duplicate]
(8 answers)
Closed 7 years ago.
I am passing data from AJAX to my PHP. I just run a for loop to make my query. Problem with my data is that it contains single quote.
I am using single quote to enclose my parameters in the query. Query is something like
INSERT INTO myTable (column1.column2) VALUES('value1', 'value2'),
('value'1', 'value2');
I want to escape like
INSERT INTO myTable (column1.column2) VALUES('value1', 'value2'),
('value\'1', 'value2');
I just tried mysqli_real_Escape_String. It returns something like
INSERT INTO myTable (column1.column2) VALUES(\'value1\', \'value2\'),
(\'value\'1\', \'value2\');
So Query execution fails.
I don't think using htmlspeciachars is the right way for this.
Any suggestions?
You should definitely be using prepared statements. They're not that tricky.
However, if you're not going to make that jump then you just need to use mysqli_real_escape_string properly.
From the result you got, I'm guessing you wrapped the whole query in the mysqli_real_escape_string function. However you should just wrap the value in it.
i.e.
"INSERT INTO myTable (column1, column2) VALUES('value1', 'value2'),
('" . mysql_real_escape_string("value'1") . "', 'value2')";
Thats a pretty contrived way of doing things. But the idea is: only wrap the value in mysqli_real_escape_string().
I have this query
VALUES ('$name', 'img\\" . $image['name'] . "', '$category')
it is for uploading an image, and I need to upload the image location hence needing
img\imagename.jpg
I am struggling with how to insert the backslash for the img\ as one leads to an error and double enters none into the database for some reason.
Thank you
Use prepared/parameterized queries. Then you don't have to worry about escaping data yourself, and are protected from SQL injection attacks.
This is the query you should have:
VALUES (:name, :img_name, :category)
Then, using PDO and SQL placeholders you can bind your values to each insertion point in your query to be sure things are properly escaped.
Why should we escape double quotes,single quotes creating queries in PHP? are there any particular benefits when doing that? or it is just a good practice?
It is required to make your queries work and secure. Consider the following code:
$name = "O'reilly";
$sql = "INSERT INTO users (name) VALUES ('$name')";
The result SQL would become like this:
INSERT INTO users (name) VALUES('O'reilly');
Which simply doesn't work. It needs to be properly escaped:
INSERT INTO users (name) VALUES('O\'reilly');
The same applies for other special chars.
Prevent SQL injection
Consider this query:
DELETE FROM users WHERE username='$username';
Where $username is obtained from $_POST. If an attacker managed to post string like ' OR 1; -- as the $username then the query becoming this:
DELETE FROM users WHERE username='' OR 1; -- ';
which is valid and the WHERE always evaluates to true and you will have to give good explanation to your angry users.
See also: Best way to prevent SQL Injection in PHP
If you do not escape quotes, The query ends at the place of single quotes. So your query will not be executed successfully!
E.g.
$qry = "SELECT * FROM user WHERE email='test#test.com'";
It works fine but if any one enters email='test'#test.com' then query ends at 'test' only and not find any rows with that one.
So it prevents also a sql injection!
s, to prevent from SQL injection attacks.
To know SQL injection
http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php
http://www.homeandlearn.co.uk/php/php13p5.html
To prevent PHP Sql injection
https://stackoverflow.com/a/60496/781181
Is the any difference between writing
{$_GET['id']}
and
'".$_GET['id']."'
in a sql statement? both works the same
Its always a bad idea to put data from a get request directly into SQL, and there are many easy ways to prevent SQL injection.
For the simple case where you know you want a numeric ID, then you can simply force the value to be numeric and then there is no chance of SQL injection. One way might be okoman's usage of sprintf(), maybe something like this:
$sql = "INSERT INTO table VALUES(".sprintf("%d",$_GET['id']) .")";
though I think its ugly and bad form. Something like this is nicer:
$sql = "INSERT INTO table VALUES(".(int)$_GET['id']) .")";
Which simply casts the value to an int - if its not a number that can be cast to int - you'll get a "0" which may or may not be what you want.
Other alternatives (and for when your data is not supposed to be a number) include using escaping functions such as add_slashes() or the above mentioned mysql_real_escape_string().
IMHO, the best way to use database access from within PHP and very easily protect from SQL injection is to use the new PHP PDO library ( http://php.net/PDO ). This allows you to write SQL strings that contain no data whatsoever, and have the data added later inside the database server itself. In this form there is absolutely no way to do SQL injection.
Here is some example code:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$stmt = $dbh->prepare("INSERT INTO table VALUES (?)");
$stmt->bindParam(1, $_GET['id']);
$stml->execute();
As you can see, the data is not added to the SQL query itself and so no need for escaping.
Using either of these directly in a SQL statement is a VERY BAD IDEA. It allows for SQL injections. Be sure to sanitize your inputs using something like mysql_real_escape_string.
The main difference between the two is that the top can only be used inside a string that uses double quotes. The bottom, however, can be used with either double or single quotes.
As far as I know there's no difference, but should you be doing that? You're allowing unsanitised input into your sql query which means if your website is internet facing you're leaving it wide open to sql injection attacks.
Here's a Q&A you should read before going any further:
How can I prevent SQL injection in PHP?
If you use a variable - especially an associative array - in a string, you can be quite sure that it will lead to errors. It's just bad style.
I - personally - don't like the second alternative either.
sprintf( '... %d ...', $_GET[ 'id' ] );
That's my favorite way of putting a variable into a string.