I have a PHP cart that was pre developed by a company, while ordering, I added an extra field for extra information, the $_POST value of it simply gets added onto the variable $post['attr'], however when that gets serialised and put into a DB it errors if it contains things like %, !, $, etc. well it doesnt error, it sends out pending order email, takes them to paypal, lets them pay, and never verifies that the prder is actually in the DB, which its not if it had special chars in it...
I have tried different ways and read that base64 encoding can help, however that would mean scraping a lot of pre existing orders and re doing a lot of the system, anyone could help?
Thank you!
The problem you're having is that the data isn't be escaped. I'm guessing you're doing something like:
$sql = "INSERT INTO mytable (something) VALUES ('". $something ."')";
$result = mysql_query($sql);
What you need to do is escape the variable first:
$sql = "INSERT INTO mytable (something) VALUES ('". mysql_real_escape_string($something) ."')";
$result = mysql_query($sql);
My example uses MySQL, but similar functions exist for all supported databases.
Use the correct function for your database. Do not just use url encoding, or generic string escaping. The characters that need to be quoted are database-specific.
Related
Forgive me if this already exists, but I didn't see anything close enough to my issue to offer any kind of solution or path toward solving.
My Query:
$sql = "UPDATE users SET FirstName=$fname WHERE id=$id";
$fname does equal Jason. But it should be changing the sql field FirstName to "Jason". Instead, it is trying to find a field named Jason. I have tried hardcoding in "Jason", but then it says that there is an unexpected string. Hardcoding it in would actually cause issues as the data needs to be a variable so the user can change to their First Name to whatever they want. I have echo'd $id and that value is coming across correctly. My code is in php.
Long time reader of stackoverflow.com, first time poster. If there is any additional code or info that might be helpful, please let me know.
EDIT: I had not realized that variables also need to be within quotes. I assumed the quotes were specifically for hardcoded strings. Placing $fname within single quotes as '$fname' solved it. Thank you, everyone!!!
Use single quotations:
$sql = "UPDATE users SET FirstName='$fname' WHERE id=$id";
Be sure about securing your SQL query; if the $fname's value is dynamic, then you must escape special characters using mysqli_real_escape_string to avoid a very dangerous vulnerability SQL Injection.
I am trying to insert a data from a form which has about 1990 characters into mysql. How ever the insert is not working. when i var_damp the content of the variable is shows the correct content. When i set it to an empty string the insert works. I have done my research and still can't get ti to work. I am not trying to upload a file. This characters are from a textarea in my form.
Below is the insert code:
if (isset($_POST['val'])) {
$score = $_POST['val'];
$course = $_POST['course'];
$mysqli->query("INSERT INTO `evaluate` (`id`, `course`, `score`) VALUES (Null, '$course', '$score')");
Note: is score column has type TEXT in the database.
This is a common problem because most introductions to mysqli don't cover it right away even when it should be the first thing you learn. Inserting into any database, especially SQL, requires carefully escaping the values you're supplying. The way these are escaped varies depending on the platform, but the good news is that mysqli can handle it for you.
The key is using prepared statements:
$stmt = $mysqli->prepare("INSERT INTO evaluate (course, score) VALUES (?,?)");
$stmt->bind_param('ss', $_POST['course'], $_POST['val']);
$stmt->execute();
Now it's best to enable exceptions so that any errors are not ignored. Once in a while we all make little mistakes that can be a giant pain to track down if there isn't any warning about them. Exceptions make a lot of noise.
If you're just getting started with PHP and databases, you might want to evaluate using PDO which is significantly better than mysqli for a number of reasons, or a higher level database layer like Doctrine or
Propel which make using the database a lot more pleasant.
I have a single quote (') in the text and not escaping it meant that the SQL statement was been interpreted wrongly
The correct way to go, and you must always do this, is:
$score = $mysqli->real_escape_string($_POST['val']);
$course = $mysqli->real_escape_string($_POST['course']);
$mysqli->query("INSERT INTOevaluate(id,course,score)VALUES (Null, '$course', '$score')");
What I am Trying to do
What I am attempting to do is, pass values from my python application to my web api where it gets saved to my database.
The problem
The reason why I am posting is because, I can send integers, 1,2,3 to my database from my python and that saves fine. But If I send "test","ape","tree" nothing is placed in the database. (PS, the data type is varchar(6) )
I can also pass string into the database (using post) from the browser and it works.
What have done
I have created my API , database and python script that passes the data around.
Python.
import requests
load={'par':'ape12'} //This doesnt save "ape" to the database
#load={'par':'3'} //This saves "3" to the database
r=requests.post("http://my-server.com/load.php",data=load)
PHP
<?php
//Connect to DB
include ("connectDB.php");
$loadgot=$_POST['load'];
mysqli_query($con,"INSERT INTO detect(l_result)
VALUES ($loadgot)");
mysqli_close($con);
?>
Hoping someone could assist me in this regard.
Thank you
You need to pass a properly formed query to mysql. The value needs to be surrounded by quotes, but also needs to escape any characters which will break out from the quoted environment. In practice, the best solution these days is to use parametrised queries (see example) like:
$stmt = mysqli_prepare($con, "INSERT INTO detect(l_result) VALUES (?)");
mysqli_stmt_bind_param($stmt, $loadgot);
mysqli_stmt_execute($stmt);
Or if you really want to use text query (you really shouldn't), you can do:
$loadgot_safe = mysqli_real_escape_string($con, $loadgot);
mysqli_query($con,"INSERT INTO detect(l_result) VALUES ('$loadgot_safe')");
The reason why you MUST NOT use:
mysqli_query($con, "INSERT INTO detect(l_result) VALUES ('$loadgot')");
is that anyone can submit multiple values - for example value1'), ('value2 will expand to INSERT INTO detect(l_result) VALUES ('value1'), ('value2') - which is definitely not what you want.
Modify the 'ape12' to "'ape12'".
Because, in MySQL we give the query like this
INSERT INTO detect(l_result) VALUES 'Value1';
So pass the values to MySQL with quotes. But no need for the integers.
From #e4c5 comment. Users wont give the quotes while entering the input. So we ensure the query inside the script. So try to changed the code like this
mysqli_query($con,"INSERT INTO detect(l_result) VALUES ('$loadgot')");
Do I need to use mysqli_real_escape_string when reusing data from a database for a query. The data was previously escaped so it can be safely inserted into the database. I am aware that when inserting data into a database, backslashes are removed.
Thanks.
Yes, you have to re-escape data that came from a DB when you're re-using it in another query. Consider escaping to be the equivalent of gift wrapping on a present. You "wrap" some data for the database in one query. It'll UNWRAP the data and put it in the data store. When you retrieve that data again later, the wrapping's gone and the data's "dangerous" again.
e.g. consider something like this:
$name = "Miles O'Brien";
$safe = mysql_real_escape_string($name); // name becomes Miles O\'Brien
$sql = "INSERT INTO people (names) VALUES '$safe'";
$result = mysql_query($sql) or die(mysql_error());
Now that name's in the database, but the escaping you performed is NOT PRESENT anymore - it was removed by the database as it processed the query, so if you do something like this:
$sql = "SELECT name FROM people"
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_asssoc($result)) {
$name = $row['name']; // get Miles O'Brien from the DB again
here you'll literally have retrieved Miles O'Brien with no escaping at all.
$other_sql = "UPDATE ... WHERE name=$name"; <---INJECTION HERE
}
Escaping is not something you do only with "outside" data... ANY data you insert into a query string is "outside" data, even if you just got that data from the database just a few lines of code ago.
TL;DR: You can easily inject yourself.
Yes, you need it. The escapes are only used to make the query syntactically valid, they're not part of the data that's stored in the table. Any time you're interpolating strings into a query, you need to escape it.
As an example, suppose you have a table of full names, and there's someone with the last name O'Reilly. You perform a query to get this name into $lname, and then you want to use that variable in another query, e.g.
$query = "SELECT username WHERE last_name = '$lname'";
If you don't escape the string, the resulting query will be:
SELECT username WHERE last_name = 'O'Reilly'
As you can see, the quotes are not properly balanced. You need to escape it so that it will be:
SELECT username WHERE last_name = 'O\'Reilly'
However, if you use prepared queries with placeholders for these parameters, you don't need to worry about this much at all (in fact, it would be wrong to escape a variable that's bound to a placeholder, as you will then store the backslashes). This is generally preferred.
Also, consider NOT extracting and re-storing the data at all, but moving data around using SQL itself:
INSERT INTO Table1 (last_name)
SELECT last_name
FROM Table2
WHERE ...
This is also likely to be more efficient, since the data doesn't have to move between the database and the application.
That's not what escaping means.
Escaping text means inserting escape characters so that it can be inserted into a SQL string and be interpreted as the original text.
It has no effect on the actual value, unless you use the wrong escape characters.
You need to correctly escape your text every time you concatenate it into any kind of structured language.
When using SQL, you should ideally use parameters instead of concatenation.
There are a lot of misunderstanding on the topic.
People keep using improper words, and a real danger coming from such a confusion.
escaping being confused with safety
data being confused with strings
formatting being confused with trusting
One have to sort these matters out.
Otherwise we still have an accepted answer implying that using mysql_real_escape_string does produce a "safe" variable. While it is not.
Just remember to validate properly all user inputted data that you plan on using and don't allow html or javascript code to be inserted. You also need to keep in mind XSS attacks, not just MySQL Injections. A good way to prevent xss is using htmlspecialchars() to convert HTML characters into HTML entities.
I used php code from tutorial and it worked fine. But when I am rewriting it to me it gives me null. This code gives me what I want I mean it gives data in JSON format:
$q=mysql_query("SELECT * FROM people WHERE birthyear>'".$_REQUEST['year']."'");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
But this code even it looks identically doesn't work it gives null:
$q=mysql_query("SELECT username, firstname, lastname, email, phone1, skype, city, description
FROM mdl_user WHERE username LIKE'".$_REQUEST['usern']."'");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
If I don't use $_REQUEST['usern'] and am getting data in JSON. But I need to use request to search specific data. So where could be the problem. Because I trustfully don't understand. It looks the same to me.
To make a pattern with LIKE use a %. Put it around or at any end, beginning or end.
$username = mysql_real_escape_string($_REQUEST['usern']);
$q=mysql_query("SELECT username, firstname, lastname, email, phone1, skype, city, description
FROM mdl_user WHERE username LIKE '$username%'");
^
|
// You also missed this space --+
Note your query is wide open to SQL injection. Just think if someone inserts year as '; drop table people; --. Use mysql_real_escape_string to sanitize those field.
And it's better to use explicitly $_POST or $_GET,ths makes sure your data is coming from proper source.
With LIKE you can use the following two wildcard characters in the pattern.
% Matches any number of characters, even zero characters
_ Matches exactly one character
I assume that you are getting no result because your username is not the exact same as $_REQUEST['usern'], and that's why you're using LIKE in the first place. You should therefore place wildcard characters to tell MySQL to look for any characters (%) before or after your string, for example:
LIKE '%".$_REQUEST['usern']."%'
Keep in mind that this is inefficient and you should try to use only one % after the string (if this will work for you), or better yet, find another way to search the table.
Edit: Also as a user in the comments noted and I failed to mention, this particular code is vulnerable to SQL injections. You should sanitize the variable $_REQUEST['usern'] before passing it onto the query.