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);
?>
Related
I want to upgrade and make more systematic, my protection against sql injection attacks. I gather the three main methods are pdo, prepared statements and mysql_escape_string, that pdo is considered best but mysql_escape_string considered adequate if you are meticulous. I don't think I am ready to go to PDO or prepared statements as I have a lot of complicated queries involving multiple tables so this would be a huge task. But I want to make use of mysql_escape_string more programmatic.
Rather than escape every individual variable that users submit, I was thinking of escape the SQL commands with a standard function that might require some modification to handle punctuation Is this a sound approach or will escaping the whole query create problems-I do use apostrophes, backticks and %, for example. It would seem that a standard function for every sql statement would be more systematic and standard than the variable by variable approach. So question is what modifications to handle punctuation might be needed? Also, is there anything else that ought to go into the function such as htmlspecialchars and strip_tags as I gather mysql_escape_string is not 100% complete?
Here is basic function.
function safe($sql) {
$safesql = mysql_real_escape_string($sql);
return $safesql;
}
I don't think I am ready to go to PDO or prepared statements as I have a lot of complicated queries involving multiple tables so this would be a huge task.
Huge? Perhaps. Worth the effort though.
will escaping the whole query create problems
Yes. Your function will have no way of knowing if a piece of SQL is an injection attack or something you intended.
You have to escape text at the point where it is inserted into SQL. You can't insert text into SQL and then figure out which bit was SQL and which bit was text afterwards.
is there anything else that ought to go into the function such as htmlspecialchars and strip_tags
strip_tags throws data away. I wouldn't use it.
Both strip_tags and htmlspecialchars offer protection against unsafe data being inserted into an HTML document. Use them before inserting data into an HTML document, not before inserting data into SQL.
The only way to make it work with the whole query is if you write your own SQL parser, and even then, you must try to magically see which parts of the query is SQL injections. That's not possible so no, you cannot do this with the entire query at once.
Personally, I think you can safely assume that protecting your "complicated queries" on your own is much more complex and time-consuming than just using PDO, ActiveRecord or the likes. Additionally, you'll make your code more database-agnostic.
Just to clarify, you shouldn't be using mysql_real_escape_string around your whole query, only the string values you are using to build your query.
Example:
"Select Id from table where username ='".mysql_real_escape_string($username)."' limit 1";
I personally like the db-class the guys from phpBB have written. It's excellent, fast and pretty secure.
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.
How can I secure $_REQUEST before inserting to mysql database? For example following:
$message = $message = $_REQUEST['message'];
$tags = $_REQUEST['item']['tags'];
Thanks.
Depends on what you mean by "secure", and how you intend to insert the data. $_REQUEST isn't broken or anything; it's just that the data in it can be just about anything, so you'll need to "sanitize" it before you use it.
For example, if 'some_id' should only ever be an int,
$some_id = intval($_REQUEST['some_id']);
will ensure that $some_id is always an int. (Even if it didn't exist in $_REQUEST! In which case it will be 0.)
If you use prepared statements, a lot of the issues with $_REQUEST data go away -- that is, extensions like PDO and mysqli will escape parameters for you (if you use placeholders, like all good prepared statements should!), so all you have to do is make sure the data is valid. (For example, above, it'd have been a good idea to make sure $_REQUEST['some_id'] was set first -- since we didn't, we got a 0 back, which may not be valid.)
If you don't use prepared statements, then you have a little more work ahead of you. You'll need to use mysql_real_escape_string to escape strings as you feed them into the database, like so:
$some_string_sql = mysql_real_escape_string($_REQUEST['some_string']);
$id = intval($_REQUEST['id']);
mysql_query("UPDATE stuff SET some_string = '$some_string_sql' WHERE id = $id");
Note that i did this just for the query! Too many PHP noobs think they can just apply some magic formula to everything in $_REQUEST at the beginning of their script to make everything safe. You kinda can, if you're always just feeding it directly into an SQL query -- but it trashes your data if you're using it for other stuff! For example, if you write the data to a file as well, blindly escaping the data will leave you with a bunch of ugly backslashes in your file. You should never have to *un*escape your data -- it should always be escaped as you need it, for the specific purpose you intend to use it. (htmlentities for arbitrary data being printed to the screen, mysql_real_escape_string for stuff going into an SQL query.)
Also note: If you have magic_quotes_gpc enabled on your site, disable it for the reasons mentioned in the previous paragraph. Properly escaped stuff will break in the presence of magic quotes, because it's already been "escaped" once (half-assedly, hence the quotes) by PHP! Fortunately this misfeature will be removed from PHP 6, if it ever ships. But til then, if you have magic quotes enabled, you'll need to stripslashes(anything from $_REQUEST, $_GET, $_POST, or $_COOKIE) before you can properly escape it. DO NOT rely on the magic quotes -- they're a convenience thing, and not at all designed for security.
You should just not forget escaping your data when injecting them in some SQL queries.
Either use a function to escape the data :
Depending on the API you're working with :
mysql_real_escape_string,
mysqli_real_escape_string,
or PDO::quote
Or you could use Prepared Statements :
Those might seem a bit harder to understand, at first -- but they are worth investing sometime...
With mysqli,
And with PDO.
Then, of course, when using the data from the database to generate some output, the same idea applies : escape the output.
If you are generating some HTML output, you'll typically want to use something like htmlspecialchars.
Or, to allow some specific HTML tags, see HTML Purifier.
If you are generating some other kind of output, you'll have to find how to escape your data specifically for this type of output.
Use either mysql_real_escape_string() or PDO's prepared statements. I recommend the latter, as it also helps keep your queries nice and tidy.
As secure as anything could be in them.
The user can change those values to whatever they want.
So, not secure at all. Always sanitize your inputs.
There is nothing to secure.
Your database input should be just properly formatted.
For the strings it's quoting and escaping.
As long as your input data is limited to strings and you follow formatting rules, no special security required.
On the PDO::Prepare page it states,
"and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters"
Knowing this, is there a PHP function like mysql_real_escape_string() that takes care of escaping stings for PDO? Or does PDO take care of all escaping for me?
EDIT
I realize now that I asked the wrong question. My question really was, "What all does PDO take care of for me?" Which I realize now with these answers that it really only removes the need to escape the quotes. But I would still need to do any other PHP sanitize calls on the values that I pass to the execute function. Such as htmlentities(), strip_tags()...etc...
PDO does not escape the variables. The variables and the SQL command are transferred independently over the MySQL connection. And the SQL tokenizer (parser) never looks at the values. Values are just copied verbatim into the database storage without the possibility of ever causing any harm. That's why there is no need to marshall the data with prepared statements.
Note that this is mostly a speed advantage. With mysql_real_escape_string() you first marshall your variables in PHP, then send an inefficient SQL command to the server, which has to costly segregate the actual SQL command from the values again. That's why it's often said that the security advantage is only implicit, not the primary reason for using PDO.
If you concat the SQL command and don't actually use prepared statments (not good!), then yes, there still is an escape function for PDO: $pdo->quote($string)
Very few people here understand what escaping is and when to use it.
Escaping itself does not make any data "safe". It just escapes delimiters, to distinguish a delimiter from a part of data. field = 'it's me' will cause an error, while field = 'it\'s me' will not. That's the only purpose of escaping. So, it works only when you use quotes. If you don't - escaping becomes useless.
Do you use quotes with placeholders? No. Thus, no escaping would be sensible.
When you are binding your variables, it works a very different way: it does not send the whole query to the server, but sends your prepared query separated from the bound data. So it cannot interfere. And thus makes no injection possible.
Yes and no:
Literals which you embed into the statement string need to be escaped as normal.
Values which you bind to the prepared statement are handled by the library.
If you prepare a statement and use bindParam or bindValue to supply variables, you do not need to escape the variables. Note that these functions assume that the variable contains a string, so use the third parameter to bindValue if you want to use booleans or floats.
You don't have to worry about it. PDO does not require you to escape your data before passing it along to the database.
Edit: Just to be clear, I mean to say that as long as you are passing variables into your parameters (for example, the value of a form field), you don't have to worry about it. However, if you're passing variables that you've defined as strings, for example, then obviously you need to escape anything that needs escaping in that string in order to avoid breaking syntax. However, this wouldn't even make much sense since one of the main advantages of PDO is that you're passing information from the user to the database without having to sanitize it yourself, and there aren't many times (if any?) that you would be passing strings that you yourself had defined.
Also, make sure you still sanitize your data for type. For example, make sure it's an integer if you expect it to be, make sure it's less than or greater than x if you expect it to be, etc.
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.