Problems with mysql insert - php

My php script won't work if i try to insert into database something in Saxon genitive (for example value "mike's" won't be inserted).
PHP code is plain and simple:
"INSERT INTO cache (id,name,LinkID,number,TChecked) VALUES(".$idUser.",'".$LinkName."',".$LinkID.",".$number.",NOW());"
Everything works great until "$LinkaName" get some value with "special character". How to put values like "mike's", "won't" etc. into MySql database?

You need to escape these strings properly. In addition, the technique that you're using right now exposes you to an SQL injection attack.
The PHP docs for mysql_real_escape_string gives a good example of what you should do:
// Query
$query = sprintf("INSERT INTO cache (id,name,LinkID,number,TChecked) VALUES(%d,'%s',%d,%d,'%s');",
mysql_real_escape_string($idUser),
mysql_real_escape_string($LinkName),
mysql_real_escape_string($LinkID),
mysql_real_escape_string($number),
mysql_real_escape_string(NOW()));

You must escape them first, otherwise you generate an invalid query. The single quote matches the single quote at the start of the string.
$LinkName = mysql_real_escape_string($LinkName);
You can also use prepared statements to bind parameters to the query instead of concatenating and sending a string (use the PDO or mysqli libraries instead of the mysql lib).

You need to use mysql_real_escape_string() on those values.
Also make sure if you are not quoting those other variables, to cast them to integer (the only reason why you wouldn't quote them).

If you're using mysqli or PDO and not the standard extension, you can use a prepared statement instead of escaping.

Related

PHP & MySql query with apostrophes

I have the following php version:
PHP Version 5.3.2-1ubuntu4.19
and this php string:
$l_sDesc = "It doesn' t contain any dangerous substances";
If i try to make a query with db_query (Drupal) i get an error due to the apostrophe;
db_query("UPDATE mytable SET description= '$l_sDesc' where id = $id");
I've tried to use mysql_real_escape_string() but i get an empty string:
$l_sDesc = mysql_real_escape_string($l_sDesc); //i have an empty string as result
What's the problem?
Drupal use another DB Wrapper. Normally you can create prepared statements.
https://api.drupal.org/api/drupal/includes!database!database.inc/group/database/7
Here is a correct example. If you use the correct prepared statements your input will be filtered.
Otherwise use stripslashes().
http://php.net/manual/de/function.stripslashes.php
Tom, you need to "prepare" the string for SQL before you actually run the statement.
Try the PHP function mysql_real_escape_string on your strings before you actually use them.
http://php.net/manual/en/function.mysql-real-escape-string.php
I suggest to use $l_sDesc = htmlspecialchars($l_sDesc);

When I update an sql table row with a content "=" there runs an error

I want to run this:
UPDATE users SET about="$about" ;
but when my $about contains =, the script makes a mistake and do something like this:
$about="<img src=somevalue.jpg />";
The script adds this in the database:
<img src
and nothing more.
try it by using double single quotes.
$about = '<img src=somevalue.jpg />';
$query = "UPDATE users SET about='$about'";
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
This is called 'sql injection'. You have to take care of that anyway, so google it.
You have to escape all input you want to use inside statements, anything can happen otherwise. Best is not to use statements constructed by simply including variable content, but use a better engine. Take a look at PDO and the way it works. You "prepare" a statement and hand over parameters as an array. PDO takes care to cleanly escape as required. Much safer that way.
The issue is with putting quotes around string. I'm not very familiar with how php replaces variables in strings but you can try following for MS SQL server:
Set about ="'$about'"

Do I need to use addslashes() when backing up database?

I am using the code shown here, it uses addslashes() on the data fetched from the database before saving to file.
$row[$j] = addslashes($row[$j]);
My question is why and do I need to use this? I thought you would do this when saving to the database not the other way round. When I compare the results from the above script with the export from phpMyAdmin, the fields that contain serialized data are different. I would like to know if it would cause any problems when importing back into the database?
Script:
'a:2:{i:0;s:5:\"Hello\";i:1;s:5:\"World\";}'
phpMyAdmin Export:
'a:2:{i:0;s:5:"Hello";i:1;s:5:"World";}'
UPDATE
All data is escaped when inserting into the database.
Change from mysql to mysqli.
SQL file outputs like:
INSERT INTO test (foo, bar) VALUES (1, '\'single quotes\'\r\n\"double quotes\"\r\n\\back slashes\\\r\n/forward slashes/\r\n');
SOLUTION
Used $mysqli->real_escape_string() and not addslashes()
inserting to db
When inserting data to a MySQL database you should be either using prepared statements or the proper escape function like mysql_real_escape_string. addslashes has nothing to do with databases and should not be used. Escaping is used as a general term but actually covers a large number of operations. Here it seems two uses of escaping are being talked about:
Escaping dangerous values that could be inserted in to a database
Escaping string quotes to avoid broken strings
Most database escaping functions do a lot more than just escape quotes. They escape illegal characters and well as invisible characters like \0 ... this is because depending on the database you are using there are lots of ways of breaking an insert - not just by adding a closing quote.
Because someone seems to have missed my comment about mentioning PDO I will mention it again here. It is far better to use PDO or some other database abstraction system along with prepared statments, this is because you no longer have to worry about escaping your values.
outputting / dumping db values
In the mentioned backup your database script the original coder is using addslashes as a quick shorthand to make sure the outputted strings in the mysql dump are correctly formatted and wont break on re-insert. It has nothing to do with security.
selecting values from a db
Even if you escape your values on insert to the database, you will need to escape the quotes again when writing that data back in to any kind of export file that utilises strings. This is only because you wish to protect your strings so that they are properly formatted.
When inserting escaped data into a database, the 'escape sequences' used will be converted back to their original values. for example:
INSERT INTO table SET field = "my \"escaped\" value"
Once in the database the value will actually be:
my "escaped" value
So when you pull it back out of the database you will receive:
my "escaped" value
So when you need to place this in a formatted string/dump, a dump that will be read back in by a parser, you will need to do some kind of escaping to format it correctly:
$value_from_database = 'my "escaped" value';
echo '"' . $value_from_database . '"';
Will produce:
"my "escaped" value"
Which will break any normal string parser, so you need to do something like:
$value_from_database = 'my "escaped" value';
echo '"' . addslashes($value_from_database) . '"';
To produce:
"my \"escaped\" value"
However, if it were me I'd just target the double quote and escape:
$value_from_database = 'my "escaped" value';
echo '"' . str_replace('"', '\\"', $value_from_database) . '"';
I think you are mixing two problems. The first problem is SQL Injection and to prevent this you would have to escape the data going into the database. However by now there is a far more better way to do this. Using prepared statements and bound parameters. Example with PDO:
// setup a connection with the database
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// run query
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array(':name' => $name));
// get data
foreach ($stmt as $row) {
// do something with $row
}
The other thing you would have to worry about it XSS attacks which basically allows a possible attacker to inject code into your website. To prevent this you should always use htmlspecialchars() when displaying data with possible information you cannot trust:
echo htmlspecialchars($dataFromUnsafeSource, ENT_QUOTES, 'UTF-8');
All data is escaped when inserting into the database.
When using prepared statements and bound paramters this isn't needed anymore.
Should I use addslashes() then use str_replace() to change \" to "?
addslashes() sounds like a crappy way to prevent anything. So not needed AFAICT.
Another note about accessing the database and in the case you are still using the old mysql_* function:
They are no longer maintained and the community has begun the deprecation process. See the red box? Instead you should learn about prepared statements and use either PDO or MySQLi. If you can't decide, this article will help to choose. If you care to learn, here is a good PDO tutorial.
You should store data without modifying them.
You should perform the needed escaping when outputting the data or putting them "inside" other data, like inside a database query.
just use mysql_escape_string() instead of addslashes and ereg_replace as written in david walsh's blog.
just try it it'll be better. :)

Why does my mysql_real_escape_string not work?

I have read many about SQL-Injection. But it does not work with this code:
$inputform= $_GET["password"];
$query = "INSERT INTO user(password) VALUES ('".mysql_real_escape_string($inputform)."')";
For example I use this example: O'Conner. When I submit it and look in my table there is O'Connor and not O\'Conner.
thanks
The quote is escaped so that MySQL doesn't interpret it as a string delimiter. The backslash doesn't get stored in the database, and it's not supposed to either. What you're seeing is the correct, expected and documented behaviour.
The best solution, BTW, is to use PDO and parametrized queries.
mysql_real_escape_string() escapes the value so that the SQL parser for MySQL can interpret the value correctly when it stores the value, it is not actually stored in the database as an escaped string
If you get O'Connor in your table, it's working properly. But try echo $query and you'll see the results of the escaping.
It works just fine! There shouldn't be "O\'Conner" in your database, just in the query. If it didn't work, your query wouldn't succeed, because the ' in O'Conner would ruin your query.
When you look in the table, it should be O'Connor - that means the string was escaped properly in the SQL. If it hadn't been escaped by mysql_real_escape_string, you probably would have ended up with a syntax error.
The query would end up as:
INSERT INTO user(password) VALUES ('O'Connor)
If you want the backslashes in the DB, try using addslashes before you pass it to mysql_real_escape_string, but you probably don't.

use mysql_real_escape_string() but allow names with apostrophes

I use mysql_real_escape_string() to validate all user inputs before I insert them in a sql database. One of the fields is name, and we've had issues with users with names like O'Reilly. Is there any way to use mysql_real_escape_string() to block injections but allow these names in the db?
The problem is most likely that the apostrophes get quoted twice: first by the evil and deprecated in 5.3 magic quotes and then by mysql_real_escape_string().
What you can do is either disable magic quotes or run stripslashes() on your input values before feeding them to mysql_real_escape_string()
Brief explanation of the problem:
the user enters O'Reilly
magic quotes automatically turn it into O\'Reilly
the script feeds the string through mysql_real_escape_string() which escapes both the backslash and the apostrophe (again) yielding O\\\'Reilly
the query is executed, the quoting is processed and the database understands that you want a backslash and an apostrophe since they where both escaped, and records O\'Reilly
As already mentionned : mysql_real_escape_string is not meant for input validation. If you want to validate inputs, use your own functions or the filter functions from php.
If you have too many slashes added automatically by php, disable magic quotes.
To prevent SQL injection, use parameterized queries with either PDO or mysqli.
+1 for using PDO. I've been using PDO in favour of a MySQL class acting as a database abstraction layer for a few months now and it's a breeze.
Traditionally, developers would use the stripslashes() function on data before applying a function like mysql_real_escape_string(). It's still a good idea to remove slashes from input data, but you can then either use the PDO method for escaping data (PDO::quote($data)) or binding the parameter.
Your query block would then look something like this:
$pdo = new PDO(DSN, DB_USER, DB_PASS);
$sql = "INSERT INTO table (field1, field2) VALUES (:value1, :value2)";
$smt = $pdo->prepare($sql);
$smt->bindParam(':value1', $value1, PDO::PARAM_STR);
$smt->bindParam(':value2', $value2, PDO::PARAM_STR);
$smt->execute();
$rows = $smt->rowCount(); // returns number of rows affected
I hope this helps somewhat. Take a look at http://php.net/manual/en/book.pdo.php for more information on PDO in PHP.

Categories