MySQL is not letting me use "s and 's with a context form I made for my site. All of the other fields sent to the database just fine, but the longtext one also makes an error if you use anything other than letters and numbers.
I have it at long text, not null.
I am trying to put mysql_real_escape_string() in my code
Use parameterized query then you don't have to worry about escaping special characters and it is safer too (ie against SQL injection attack).
find function in your programming language that escapes slashes and similar and apply it to your output before sending to database
This should work as proposed
$sql2="INSERT INTO $tbl_name(s_id, s_name, s_email, s_content) VALUES(".$id.", '".mysql_real_escape_string($s_name)."', '".mysql_real_escape_string($s_email)."', '".mysql_real_escape_string($s_content)."')";
You should: Take advantage of prepared statements and if you don't do that escape ALWAYS!!! values that come from client input. If not your website can easily been hacked by script-kiddis that just test some sql-injections.
it is better to use prepared statements then the method you have adopted, the plus point of using Prepared Statements like PDO are, it will save you from attacks Such as MYSQL Injections and there are lot more, basically PDO is an inbuilt PHP class which lets you interact with your database at ease, plus it is very flexible, for example,
To establish a connection using PDO you just need to use one line of code, it is like initializing an object.
$dbh = new PDO('mysql:host='.HOST.';dbname='.DATABASE,USERNAME,PASSWORD);
that's it, please note i have used Constant, you can replace it with you own.
now for example if you want to select something using PDO, you just need to write one line of code.
$sth = $dbh->query('SELECT id,name FROM table');
//Query is executed in the above code, and when you want to retrieve the value you just need another line of code.
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
that's it, now you have an array $result which holds all the retrieved value. isn't it very simple and easy to use?
to get you started with using PDO here take a look at this tutorial in net.tutsplus.com
they have explained it very well.
Related
I read this comment on the mysql_real_escape_string php documentation page:
Also don't forget to escape $_COOKIE array before querying the database. In firefox you can edit cookies and insert and inject harmful sql queries.
<?php
foreach ($_COOKIE as $key => $value) {
if(get_magic_quotes_gpc()) $_COOKIE[$key]=stripslashes($value);
$_COOKIE[$key] = mysql_real_escape_string($value);
}
?>
Am I right in thinking I only have to do this if I use these cookie values in a query? So if no sql statement uses values from these cookies there is no need to escape the cookies like above?
I am using mysql_query not prepared statements (all the inhouse company code I am working with uses mysql_query)
You just need to remember this concept once: Whenever you concatenate one string into a special text format, you need to escape it according to that format at the moment of concatenation. It doesn't matter where that value comes from. You do not escape values before or after concatenating them, but right when you do. You do not blanket escape your cookie values just because. You escape a value you want to put into an SQL query right when you put it in there. Cookies are no special case; it's sad enough that the reminder needs to be there.
Your code is always:
$sql = sprintf("SELECT ... WHERE foo = '%s'", mysql_real_escape_string($var));
It's not:
$var = mysql_real_escape_string($var);
// 100 lines of irrelevant code
$sql = "SELECT ... WHERE foo = '$var'";
Read The Great Escapism (Or: What You Need To Know To Work With Text Within Text).
Am I right in thinking I only have to do this if I use these cookie values in a query?
Yes... ish.
You shouldn't overwrite superglobals with data that is only fit for stuffing in a MySQL query. Do escaping at the last minute and to local variables.
There are better ways to defend against SQL injection then variable escaping anyway.
I am using mysql_query not prepared statements (all the inhouse company code I am working with uses mysql_query)
I suggest starting the migration process. It will be less painful then having to do it all in one go when you want to upgrade to a future version of PHP that doesn't have the deprecated library in it.
Yes, you are right in assuming this is only required when using them in database queries.
No, you should definitely not do it globally for ALL cookies.
No, you should never concatenate cookie values in SQL queries anyway, use prepared statements.
mysql_real_escape_string is deprecated with its entire family of mysql_ functions since PHP 5.5. Switch to PDO or MySQLi instead. And use their faciliteit for prepared statements to remove all worries about SQL injection.
You can edit cookies in every browser, not just Firefox.
Am I right in thinking I only have to do this if I use these cookie
values in a query? So if no sql statement uses values from these
cookies there is no need to escape the cookies like above?
yes, of course ;)
I am using mysql_query not prepared statements (all the inhouse
company code I am working with uses mysql_query)
Try to migrate to prepared statements with either PDO or mysqli
If you cannot migrate: Note that you'll have to establish the mysql connection before you call mysql_real_escape_string()! That's because the function uses the current connection encoding to properly escape strings. If you connect afterwards the escaping might be wrong.
This reminder is there to tell you, that you can't trust values you get from cookies, even if you set them yourself, because anyone can alter them. So, yes.
Of course you should not use mysql_ functions and all that, but I think you know that (have to use them in an older application, too).
I inherited a moderately large sized code base that makes extensive use of mysql_fetch_assoc and mysql_fetch_object, and doesn't have any security precautions preventing SQL injection. I decided that this was a Very Bad ThingTM that needed fixing.
Initially, I intended on moving to mysqli prepare/bind_param/execute statements to handle DB queries. However, the following does not work:
$stmt = $GLOBALS['db']->prepare('SELECT * FROM Users WHERE Username=?');
$stmt->bind_param('s', $username);
$stmt->execute();
// Somehow retrieve the fetched row as an object (Doesn't work!)
return $stmt->fetch_assoc();
Question 1: Is there a way to use fetch_assoc or fetch_object using prepare/bind? I can refactor all the code, but it would be messy and take a very long time.
Question 2: If it is not possible to do this, is it just as effective from a security standpoint to use mysqli_query(), provided all inputs are properly escaped via mysql_real_escape_string()? Do you have any other suggestions?
$row = $stmt->fetch(PDO::FETCH_ASSOC) Ref: http://php.net/manual/en/pdostatement.fetch.php
You can use mysqli if you want. As long as you use the real_escape_string functions on ALL user data (including your own) that's going into SQL statements, then it's no less secure than using prepared statements - it's just much easier to miss a post and leave a hole open.
Replacing raw mysql with raw mysli makes very little sense.
in fact, all those doleful repetitive prepare/bind/execute/fetch being as ugly as mysql_query/fetch.
If you going to refactor your code anyway, you have to develop some library function, which will take a query and it's prameters as arguments and return an array of data, doing all the fetching inside.
as for the escaping all inputs via mysql_real_escape_string(), it is going to be an equivalent of magic quotes, which, at last, been acknowledged as a bad practice.
in fact, mysql_real_escape_string() doesnt make any data safe. it has nothing to do with safety at all. it's merely a formatting routine, and works only for strings. But there are other types to insert into query. For the detailed explanations refer to my prefious answer, How to include a PHP variable inside a MySQL insert statement
I am trying to create some SQL insert statements and a few variables have names like the following:
"Aamma's Pastries"
I want to escape the quote (') as I am adding the value into the MySQL database. How do I do that with PHP?
You've already accepted an answer, but I'd like to suggest a better approach to you. Using an approach like mysql_real_escape_string requires you to consistently remember to apply it every single time in every single query; it's tedious and error prone.
A more simple approach, which also ensures consistency is to use parameterised statements. This ensures that everything is correctly escaped, and also avoids you having to embed variables in your queries.
In PHP, this can be used with the newer PDO or MySQLi libraries. Of these, I prefer PDO for the flexibility it provides (e.g. I'm currently stuck with MySQL, but I don't intend to keep my app running that way forever, and with PDO the migration will be massively simplified), but there are plenty of questions here on SO that cover the pros and cons of each.
Have a look at mysql_real_escape_string
Please use prepare statements and let mysql handle escaping itself and you doing at code level
There is this function that you can use that escapes all characters that you need, here is a code example in php
<?php
$str = "Is your name O'reilly?";
// Outputs: Is your name O\'reilly?
echo addslashes($str);
?>
Is mysql_real_escape_string supposed to replace both addslashes() and stripslashes()??
ie.. do I use it to encode form input variables on MySQL inserts as well as use it in place of stripslashes on MySQL select statements?
Sincerely,
Confused PHP noob
If you are using the regular MySQL driver module for PHP, then yes, mysql_real_escape_string() is the way to go. You can ignore addslashes() and stripslashes() entirely, in fact.
Your query creation will look something like this:
$sql = "INSERT INTO tbl (x) VALUES '".mysql_real_escape_string($x)."'";
mysql_real_escape_string() should be used on any user input that is going into your query. Note that you don't want to escape your data any other way before inserting it. You shouldn't use addslashes() or htmlentities(), which are common mistakes when storing HTML fragments in a database. You should not need to unescape your data in any way after you have retrieved it.
As other posters mention, there are other MySQL database driver modules for PHP, including PDO and MySQLi. Both offer a feature known as prepared statements, which is an alternative method of creating queries that handles escaping for you.
I recommend using PDO and prepared statements instead; see the PDOStatement class. Prepared statements can be more efficient (if the engine doesn't have to reparse your SQL). They should also prevent you from accidentally storing escaped data in the db (double-escaping). Using PDO will make it easier to add support for other databases.
Yes, it should do all the backslashing for you (based upon whatever charset the mysql server is)
Yes, it should escape strings in preparation for use in MySQL. However, it is not the be-all, end-all of avoiding SQL injection. It does in fact leave you very vulnerable to it still.
Better to use the PHP PDO instead, parameterized queries are the way to go ;)
I'd recommend using prepared statements. That way you won't have the hassle of manually escaping every query.
$stmt = $db->prepare("SELECT stuff FROM table WHERE something = ?");
$stmt->execute('s', 'something'); // s means string
Another option is to use PDO, which is an even better version of this, and generally database independent.
http://php.net/manual/en/function.mysql-real-escape-string.php
You wouldn't want to use addslashes() and stripslashes(). If I recall correctly, mysql_real_escape_string() is more similiar to addslashes(), but it escapes different characters.
PDO and prepared statements are still kind of confusing to me, no matter how much I read about them so far. So I know they are more "secure" but is it really that important? I mean I can get the same end result using basic mysql with mysql_real_escape_string() and htmlspecialchars() right?
You could, but PDO and prepared statements are the absolute safest. Could you do it by hand and use the mysql_real_escape_string() function? Sure. In fact, your output might look identical. But in the end, the code that PDO would require would be a hell of a lot shorter than the code if you had done it manually.
Also, if you aren't using prepared statements, you run the risk of human error: say you forget to escape a value or sanitize an input. Mixed in with all of your other code, the one line that isn't properly sanitizing could crop up to be a nightmare down the road.
Hope this helps!
I really like the PDO interface. Once you get used to it, it's a lot cleaner than the mysql_* function style. It took me a while to figure it out, too, but it's worth it.
The part that I found confusing was remembering what methods belong to the PDO DB connection object itself, and which are part of the statement objects.
With certain actions, you'll get a performance benefit from repeating prepared statements, too. For instance, if you're doing a bunch of inserts in a loop, you can prepare the statement, and then bind new data in the loop each time before inserting.
The security is much better too, in that you are relying on a well tested library to escape your data on each insert. It's like cryptography - why do it yourself, when it's something this important? There's no reason to give yourself a chance to get it wrong (i.e., accidentally miss escaping something inserted into a query).
I recommend this guide to PDO, from the author who wrote this excellent giant book on Mysql.
I like to use the positional parameter style, and then you just make an array of the data and pass it in. My queries look like
$pdo_db=pdo_connect('cow_db');
$sql='select this,that,count(those) as snout from lovely_table where name=? and horses=?';
$data=array($username,$horse_count);
$query_stmt=$pdo_db->prepare($sql);
$result_handle=$query_stmt->execute($data);
//then I have a function to load data from the result handle
$info=load_array($result_handle);
You could make functions like this to work with the standard php mysql interface, but why not just use PDO?
I agree with others who say using prepared queries is generally better than using escaping functions. It's easier to use correctly, and there's no way that parameter values can introduce SQL injection problems, since the value are sent to the RDBMS server separately from the SQL query.
However, using parameters is useful only when the dynamic parts of your SQL query is a parameter in lieu of a literal value in an expression. You can't use a query parameter in place of a table name, column name, an SQL expression, or a list of values (e.g. arguments of an IN( ) predicate).
Prepared queries also have better performance than non-prepared queries (at least in MySQL). Most people say the opposite, but the well-respected mysqlperformanceblog.com did the testing:
http://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/
As long as you sanitize data appropriately for your queries then you don't have to use PDO/prepared statements. Though, I would personally recommend using PDO/prepared statements simply because they do both make development/debugging easier and prepared statements prevent incorrect data types from even getting in to a query.
If you want to learn more about how to create a simple prepared statement look in to the function sprintf. You simply replace any variable strings, integers, etc with a type specifier (in this case %s and %d respectively).
So for example in the following query, I know that id is going to be an integer (it will be numerical) and name will be a string (alphanumeric).
$username = 'Simon';
$id = 3;
$query = "SELECT FROM `users` WHERE `id` = {$id} AND `name` = '{$username}'";
If I'm getting either of this variables from an un-trusted source (such as a POST/GET) then I can make sure they are the correct data types by replacing the final line (the $query set) with a sprintf call like this:
$username = 'Simon';
$id = 3;
$query = sprintf( "SELECT FROM `users` WHERE `id` = %d AND `name` = '%s'", $id, $username );
sprintf will simply not let me use a string for the $id or an integer for the $name when it is called which ensures the correct types of data are given (this gives me that little extra bit of security). IF incorrect data types ARE given then I believe it'll cast the variables to the requested type.
To read more about sprintf visit here: http://php.net/sprintf
I hope this explains enough (it's my first answer) :).
you could try zend_db which uses pdo under the hood. (mdb2 is another option you can use.)
PHP lets you do anything you want, and it just so happens PDO does what "you want" with a lot less code. :)