I wrote a script to insert record in my DB. The only issue I am getting is when I try to store data which contains ' character then the script does not work and it does not store anything in the DB. For example John's Birthday , Amy's Home etc . Any solution to this problem which allows special character like ' to store in the DB and retrieving them without any harm to security?
mysqli_query($con,"INSERT INTO Story (desc)
VALUES ('$mytext')");
PHP's mysqli_real_escape_string is made specifically for this purpose. You problem is that quotes are being interpreted by MySQL as part of the query instead of values. You need to escape characters like this so they won't affect your query - this is what SQL injection is.
$mytext = mysqli_real_escape_string($con, $mytext);
// continue with your query
Manual: http://php.net/manual/en/mysqli.real-escape-string.php
Filter the variable part of the query through mysqli_real_escape_string.
Related
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
I am beginning the process of coverting all of my MySQL to MySQLi.
I have been doing much research on this but find it a bit confusing.
I have two questions at this point regarding the matter:
1) What does it exactly mean to "escape" a string and where does the code for this go? I assume it goes on my page with my database login credentials.
I found the following but find it somewhat hard to interpret:
"We'll use the mysqli_real_escape_string() function. Since it needs a database connection, we'll go ahead and wrap it in its own function. In addition, since we only need to escape strings, we might as well quote the value at the same time:"
`
function db_quote($value) {
$connection = db_connect();
return "'" . mysqli_real_escape_string($connection,$value) . "'";
}
`
"If we are not sure of the type of value we pass to the database, it's always best to treat it as a string, escape and quote it. Let's look at a common example - form submission. We'll use our previous INSERT query with user input:"
`
// Quote and escape form submitted values
$name = db_quote($_POST['username']);
$email = db_quote($_POST['email']);
// Insert the values into the database
$result = db_query("INSERT INTO `users` (`name`,`email`) VALUES (" . $name . "," . $email . ")");
`
2) After I have this set up in my code, how do I properly test that it is indeed working (Without completly wiping out my tables, etc?)
I just really need some further explanations on this subject before I begin the process.
Any resources, advice, or pointers in the right direction would be greatly appreciated.
Escaping a string means converting characters that would be treated as special in a query as literal characters. A good example is a single quote. This has special meaning in a query, and attackers can use it to alter the functionality of the query to bypass security. Escaping that character makes it non-functional as part of the query such that it only contributes to a string value. Details on that can be found by studying SQL injection attacks.
As for where it goes, anytime you build a query with uncontrolled values, those values should be escaped.
**After I have this set up in my code, how do I properly test that it is indeed working (Without completly wiping out my tables, etc?)**
My preference is a combination of extracting the final query for manual testing, and extensive use of a test database so that the integrity of your production database isn't affected during development.
The table has company names which are not escaped.
My qry looks like
$sql = "SELECT id FROM contact_supplier WHERE name = '$addy' LIMIT 1";
The problem comes in where the company name values in the table are sometimes things like "Acme Int'l S/L".
(FYI: values of the $addy match the DB)
Clearly, the values were not escaped when stored.
How do I find my matches?
[EDIT]
Ahah!
I think I'm we're on to something.
The source of the $addy value is a file
$addresses = file('files/addresses.csv');
I then do a
foreach ($addresses as $addy) {}
Well, when I escape the $addy string, it's escaping the new line chars and including "\r\n" to the end of the comparison string.
Unless someone suggests a more graceful way, I guess I'll prob strip those with a str_replace().
:)
[\EDIT]
Why do you think the data already stored in the table should be escaped?
You should escape data only right before it is written directly into a text-based language, e.g. as a part of an SQL query, or into an HTML page, or in a JavaScript code block.
When the query is executed, there's nothing espaced. MySQL transforms it and inserts, otherwise it wouldn't insert and gives error because of syntax or we escape them for security like sql injection.
So your query with escaped values will be working fine with the data in your database.
If the values were not escaped when stored then they would have caused SQL errors when you tried to enter them.
The problem is that the data is not being escaped when you make the query.
Quick hack: Use mysql_real_escape_string
Proper solution: Don't build SQL by mashing together strings. Use prepared statements and parameterized queries
Another option would be to change your query to this...
$sql = "SELECT id FROM contact_supplier WHERE name = \"$addy\" LIMIT 1";
Use mysql_real_escape_string:
$addy = mysql_real_escape_string($addy);
Or try using parameterized queries (PDO).
Regarding this statement:
Clearly, the values were not escaped when stored.
This is incorrect logic. If the values weren't escaped in the original INSERT statement, the statement would have failed. Without escaping you'd get an error along the lines of syntax error near "l S/L' LIMIT 1". The fact that the data is correctly stored in the database proves that whoever inserted it managed to do it correctly (either by escaping or by using parameterized queries).
If you are doing things correctly then the data should not stored in the database in the escaped form.
The issue turned out to be new-line characters
The source of the $addy value starts out like this
$addresses = file('files/addresses.csv');
I then goes through
foreach ($addresses as $addy) {}
When I escape the $addy string, it's escaping the new line chars and inserting "\r\n" on the end of the comparison string.
As soon as I dropped those chars with string_replace() after escaping, everything went swimmingly
Thanks-a-BUNCH for the help
I have a TextArea on my website which I write the input into my database.
I want to filter this TextArea input, but without removing any HTML tags or other stuff.
In short, I want to sanetize and securize the input before I write it into my database, but I want the entry to be intact and unmodified when I take back the entry from the database and write it on the website.
How can I achieve this?
If you want to preserve the data character for character when it's written back to the website try:
$stringToSave = mysql_real_escape_string($inputString);
Then when retrieving it from the database:
$stringToPutOnPage = htmlentities($databaseString);
If you want the html to actually be read as html (be careful about XSS) you can just use:
$stringToSave = mysql_real_escape_string($inputString);
Edit: It would seem that best practice is to sanitize the string for html after retrieving it from the database and not before. Thanks for the comments, I will have to change my method.
If you mean you simply want to make it safe to store in your database all you need to do is use the database specific escaping method, for example mysql_real_escape_string. Of course, that doesn't secure you from XSS attacks, but if you want to retrieve and display it unmodified you don't have a choice.
It's really simple:
To avoid SQL injection, mysql_real_escape_string your values before concatenating them into an SQL query, or use parameterized queries that don't suffer from malformed strings in the first place.
To avoid XSS problems and/or messed up HTML, HTML escape your values before plugging them into an HTML context.
JSON escape them in a JSON context, CSV escape them in a CSV context, etc pp.
All are the same problem, really. As a very simple example, to produce the string "test" (I want the quotes to be part of the string), I can't write the string literal $foo = ""test"". I have to escape the quotes within the quotes to make clear which quotes are supposed to end the string and which are part of the string: $foo = "\"test\"".
SQL injection, XSS problems and messed up HTML are all just a variation on this.
To plug a value that contains quotes into a query, you have the same problem as above:
$comment = "\"foo\""; // comment is "foo", including quotes
$query = 'INSERT INTO `db` (`comment`) VALUES ("' . $comment . '")';
// INSERT INTO `db` (`comment`) VALUES (""foo"")
That produces invalid syntax at best, SQL injection attacks at worst. Using mysql_real_escape_string avoids this:
$query = 'INSERT INTO `db` (`comment`) VALUES ("' . mysql_real_escape_string($comment) . '")';
// INSERT INTO `db` (`comment`) VALUES ("\"foo\"")
HTML escaping is exactly the same, just with different syntax issues.
You only need to escape your values in the right context using the right method. To escape values for HTML, use htmlentities. Do that at the time it's necessary. Don't prematurely or over-escape your values, only apply the appropriate escape function in the right context at the right time.
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.
I currently have this code
$main_cat = "Antiques-collectables";
$mcat = "0187-1443";
$sub_cat = "toys";
mysql_query("
INSERT INTO categories
(id, main_cat, sub_cat, mcat)
VALUES
('', '$main_cat', '$sub_cat', '$mcat')
");
For some reasons the $mcat value is not stored properly . When I check it in the database it appears as "1" , "347" values etc ... only 1 or 3 digits value . I think that the "-" is interpreted by the sql engine as operator . Is there any way to escape it ? I also tried
$mcat = str_replace("-", "\-", $mcat);
but still doesn't work .
When you are inserting strings into the database, you need to make sure to use mysql_real_escape_string() on them. This prevents any unintentional problems, and also SQL injections which can really cause a lot of problems for your site.
You can, also, look at using prepared statements, which effectively eliminate this problem.
You didn't mention your data type of column in your table.
I think datatype of mcat is numeric type.
Probably by changing mcat data type to string solve your problem.
No, '-' is not a SQL operator when within single quotes (as you have it there).
The mcat column probably has the wrong data type. Is it a VARCHAR? To store what you've got there, it should be.