This query not inserted when variable $subject has single quotes . Is there any possible solution available ?
mysql_query("INSERT INTO table (to_email_id,subject) values('$to','$subject');");
Consider using Parameterized Queries using PDO for example.
Alternately, enclose your variables in brackets { }.
Edit:
I missed that your variable $subject contains single quotes. This means you have to escape them. (See the myriad of other answers and mysql_real_escape_string() about this.) But as you can see, single quotes inside the variable is exactly how injection attacks work. Escaping them helps prevent such problems as well as allow your query to store the expected data.
No answer about injection attacks is complete without referencing Bobby Tables.
Escape your parameters.
$to = mysql_real_escape_string($to);
$subject = mysql_real_escape_string($subject);
mysql_query("INSERT INTO table (to_email_id, subject) values('$to', '$subject');");
Manual: mysql_real_escape_string()
Also, please read about SQL injection attacks.
Your query will be returning a 1064 error which is a syntax error within your query. This is happening because the variables, specifically $subject in the case of the question is altering the format of your enclosed string. For example, let's say we have
$subject = "fire's hotter than it looks";
When this is evaluated in your query your query string will be
INSERT INTO table (to_email_id,subject)
VALUES('the value of the to variable','fire's hotter than it looks');
If you look at the second item in the values, which was once $subject, you'll notice you now have an uneven number of apostrophes meaning that the end of your query '); is an open string.
As commented above use a function such as mysql_real_escape_string() to add the missing slashes.
Quick note: adding slashes to characters such as " and ' (\", \'). tells mysql to interpret these as string characters instead of query string delimiters.
You need to use mysql_real_escape_string() on your values $to and $subject
Also if you weren't doing this before you are open to sql injection
USE
mysql_real_escape_string
Your query has a great "hole" -> SQL injection. You should read more about this here: http://en.wikipedia.org/wiki/SQL_injection and also here http://php.net/manual/en/function.mysql-real-escape-string.php
To make a short answer you must "escape" values passed to mysql. Best way to do it is with using mysql_real_escape_string function.
$query = sprintf("mysql_query("INSERT INTO table (to_email_id,subject) values('%s', '%s');", mysql_real_escape_string($to),mysql_real_escape_string($subject));
mysql_query($query);
I hope this will help you.
if you are using
(all book's are available) as $subject and you are trying to insert in to mysql
use this
$disc_str = addslashes($subject);
"INSERT INTO table name (subject) value('$disc_str')";
it works for me in Textarea with tinymce also
Solution is very simple. Just add below method before storing your data into php variable
$connection = mysqli_connect($host,$dbuser,$dbpass,$dbname);
$to= mysqli_real_escape_string($connection, $old_email);
$subject= mysqli_real_escape_string($connection, $old_subject)
$query = "INSERT INTO table (to_email_id,subject) values('$to','$subject');";
Related
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.
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've been coding my website in PHP lately and I was pretty proud of myself for my good practices of sanitizing my input before I used it in a query. It was all going great until my friend said I need to sanitize my input. When I tried to explain to him that it was sanitized, he showed me that he had found everything in 'users' table in my database. I didn't know how, so I thought I would post what I was doing wrong that made my sanitizing not work. Here is the PHP code he was exploiting:
start_mysql(); // Starts the databases stuff, etc.
$id = mysql_real_escape_string($_GET['id']);
$game = mysql_query("SELECT * FROM `games` WHERE `id` = $id LIMIT 0, 1");
All he was doing was changing the id parameter, making him able to use SQL injection on my database. I thought mysql_real_escape_string escaped all characters like that, but apparently I was wrong. I did some tests with a normal string to see what would happen, and this is what it said
URL: /game.php?id=' OR '' = '
echo($_GET['id']); // This echo'd: \' OR \'\' = \'
echo(mysql_real_escape_string($_GET['id'])); // This echo'd: \\\' OR \\\'\\\' = \\\'
So, my simple question is, what am I doing wrong?
You need to put the escaped string in single quotes:
WHERE `id` = '$id'
Since id was an integer parameter and you did not surround it in single-quotes in your SQL, the value of $id is sent directly into your query. If you were expecting an integer id, then you should verify that the value of $_GET['id'] is a valid integer.
$id = intval($_GET['id']);
Matt,
mysql_real_escape_string() will only filter for certain characters, if you truly want to prevent injection attacks check out this other Stack Overflow article that suggests you use Prepared statements:
Prepared Statements
PHP Manual entry on Prepared statements
Edit: Also check out Slaks and Michael's postings about wrapping your variable in single quotes.
Good luck!
H
Cast ID. If it is a string it will cast as 0.
$id = (int)$_GET['id'];
Also, MySQL support quotes around both string and numbers in the query.
$game = mysql_query("SELECT * FROM `games` WHERE `id` = '$id' LIMIT 0, 1");
You need to use the parameter binding api. The problem is in this piece of code:
WHERE `id` = $id
You are directly interpolating user input into your SQL statement. That's the open barn door for SQL injection attacks.
You're not using parameterized queries.
MDB2 allows this, though that library may be falling out of favor.
It's very likely that your configuration has magic_quote_gpc, an ancien attempt in PHP to make scripts secure magically. It proved to have multiple flaws and was since deprecated and was scheduled to be completely removed in 5.4 the last time I heard of it.
If you have access to your php.ini configuration, you should disable it. Otherwise, you can modify your script to take it into account and sanitize your input.
All of this is documented here: http://www.php.net/manual/en/security.magicquotes.disabling.php
Otherwise, there is nothing wrong with mysqli_real_escape_string().
You can't prevent SQL injections using mysql_real_escape_string(). It is used for escaping special characters like single quotes ('), double quotes ("), etc.
To prevent SQL injections you have to use PDO statements and filter functions in PHP for sanitizing the user data.
So using %27 you can just SQL inject even though data is sanitized with mysql_real_escape_string
%27) SQL INJECTION HERE %2F*
What to do?
Edit with example:
$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
mysql_real_escape_string($_GET['searchterm']),
mysql_real_escape_string($_GET['searchterm']));
$results = $db->queryAsArray($sql);
If you pass in %27) SQL INJECTION HERE %2F* to the searchterm querystring, I get outputted on the page:
You have an error in your SQL syntax;
check the manual that corresponds to
your MySQL server version for the
right syntax to use near 'BOOLEAN
MODE)' at line 1
Thanks everyone for finding the problem in the db class..
Reasoning from the method name queryAsArray, it seems that you’re using this DbBase class from the comments of the MySQL functions manual page. If so, it’s the query method that removes the escape character from the escaped quotation marks:
function query($sql, &$records = null){
$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
// …
}
Then it’s not a miracle that your example works (I simplified it):
$input = "', BAD SQL INJECTION --";
$sql = "SELECT '".mysql_real_escape_string($input)."'";
var_dump($sql); // string(33) "SELECT '\', BAD SQL INJECTION --'"
// everything’s OK ↑
$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
var_dump($sql); // string(32) "SELECT '', BAD SQL INJECTION --'"
// Oops! ↑
The note mentioned in our manual has been marked for deletion. Once it propagates across all of the mirrors in our network, it will no longer appear attached to the official documentation.
~ Daniel P. Brown
Network Infrastructure Manager
http://php.net/
It's best to not to build statements like this at all, and instead use queries with parameters using mysqli or PDO. This will deal with the problem of MySQL injection and one day (not yet, unfortunately) it will perform better too, because the queries are cached without parameters, meaning you only got one query in the cache instead of dozens of different queries because of a single input value changing all the time. Other databases make use of this since long, but MySQL just managed not to make parameterized queries slower since the latest version.
It doesn't look plausible that %27 will actually terminate the string. It seems more like a possibility to embed quotes inside a string, but I'm not sure.
To be sure, I decided to sacrificed my server and test this. When I enter %27 in an input field and textarea that are escaped using mysql_real_escape_string and are then inserted in the database, I get no errors. The text %27 is just inserted. So no problem at all.
You are wrong. No injection possible here.
By following these three simple rules
Client's encoding properly set by mysql_set_charset()
Data being escaped using mysql_real_escape_string()
And enclosed in quotes
you can be sure that no injection possible
$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
I would like to know if the above query can be exploited using SQL injection. Is there any advanced SQL injection technique that could break sprintf for this particular query?
I don't think it needs to be particularly advanced... try an input of
' OR 1 = 1 OR user='
In other words, you'll get SQL of:
select user from table where user='' OR 1 = 1 OR user=''
Does that look like a query you really want to execute? (Now consider the possibility of it dropping tables instead, or something similar.)
The bottom line is that you should be using a parameterised query.
Yes, I'd say you have a potential problem there :)
You need to escape: \x00, \n, \r, \, ', " and \x1a. sprintf() does not do that, sprintf() does no modification to strings, it just expands whatever variadic arguments that you give it into the buffer that you provide according to the format that you specify.
If the strings ARE being transformed, its likely due to magic quotes (as Rob noted in Comments), not sprintf(). If that is the case, I highly recommend disabling them.
Using sprintf doesn’t give you any more protection than using simple string concatenation. The advantage of sprintf is just having it a little more readable than when to using simple PHP’s string concatenation. But sprintf doesn’t do any more than simple string concatenation when using the %s format:
$str = implode('', range("\x00", "\xFF")); // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
You need to use functions that escape the contextual special characters you want to insert your data into (in this case a string declaration in MySQL, supposing you’re using MySQL) like **mysql_real_escape_string** does:
$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
when $_POST["user"] would equal "';SHUTDOWN;" - what would happen?
Actually, turn off magic quotes.
In PHP, where it's appropriate, use filters:
$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
Filters strip out HTML tags and escape various characters.
In addition, you can let your database escape it for you:
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
This escapes MySQL specific special characters like double quotes, single quotes, etc.
Finally, you should use parameterized queries:
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);
Parameterized queries automatically add the quotes around strings, etc., and have further restrictions that make SQL injections even more difficult.
I use all three, in that order.
Ahh here I come with the magic answer! :)
magic quotes do escaping for you!
So, you have to turn magic_quotes_gpc ini directive off
and then use mysql_real_escape_string as suggested.
Yes.
If somebody put in the following as the user in your form:
'; delete * from table
$_POST["user"] = "' or 1=1 or user='"