I propose the following question ... I have to make sure that the following query also accept values with the quotes inside ..
I tried using mysqli_real_escape_string but it did not work .. I am attaching my attempts ..
1° Put the function during the post
$idCantiere = $_POST["idCantiere"];
$nomeCantiere = mysqli_real_escape_string($_POST["nomeCantiere"]);
$sql = "INSERT INTO Cantiere(
idCantiere,
nomeCantiere)
VALUES(
'$idCantiere',
'$nomeCantiere')";
if (mysqli_query($mysqli, $sql))
{
echo "<script type='text/javascript'>alert('Cantiere Inserto');
</script>";
} else
{
echo "Error: " . $sql . "" . mysqli_error($mysqli);
}
2° Put the function during the query
$idCantiere = $_POST["idCantiere"];
$nomeCantiere = $_POST["nomeCantiere"];
$sql = "INSERT INTO Cantiere(
idCantiere,
nomeCantiere)
VALUES(
'$idCantiere',
mysqli_real_escape_string('$nomeCantiere'))";
if (mysqli_query($mysqli, $sql))
{
echo "<script type='text/javascript'>alert('Cantiere Inserto');
</script>";
} else
{
echo "Error: " . $sql . "" . mysqli_error($mysqli);
}
How can I solve the problem?
Drop the mysqli_real_escape_string() and just use prepared statements which is simple and prevents sql injections.
<?php
$idCantiere = isset($_POST['idCantiere']) ? $_POST['idCantiere'] : null;
$nomeCantiere = isset($_POST['nomeCantiere']) ? $_POST['nomeCantiere'] : null;
$sql = $mysqli->prepare("INSERT INTO Cantiere (idCantiere,nomeCantiere) VALUES(?.?)");
$sql->bind_param("is",$idCantiere,$nomeCantiere);
if($sql->execute()){
//success message
}else{
//return error
}
?>
A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency.
Prepared statements basically work like this:
Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?"). Example: INSERT INTO MyGuests VALUES(?, ?, ?)
The database parses, compiles, and performs query optimization on the SQL statement template, and stores the result without executing it
Execute: At a later time, the application binds the values to the parameters, and the database executes the statement. The application may execute the statement as many times as it wants with different values
Compared to executing SQL statements directly, prepared statements have three main advantages:
Prepared statements reduce parsing time as the preparation on the query is done only once (although the statement is executed multiple times)
Bound parameters minimize bandwidth to the server as you need send only the parameters each time, and not the whole query
Prepared statements are very useful against SQL injections, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur.
You are wrong to pass parameters to the mysqli_real_escape_string () function
before inserting the post you must put the connection string with which you access the DB
$connection=mysqli_connect("localhost","USER","PASSWORD","DB");
$nomeCantiere= mysqli_real_escape_string($connection, $_POST['nomeCantiere']);
your second attempt is wrong reuses my line of code in the first .. during the post
You have to pass the connection variable as first parameter
Eg:
$con=mysqli_connect("localhost","my_user","my_password","my_db");
$age = mysqli_real_escape_string($con, $_POST['age']);
Checkout documentation for more detail.
http://php.net/manual/en/mysqli.real-escape-string.php
You can try to replace quote with php
$nomeCantiere = $_POST["nomeCantiere"];
str_replace("'", "''", $nomeCantiere );
if you insert 2 quotes ( '' ) instead of one mysql will put that value in the table with only 1 quote
You are missing one parameter in function
mysqli_real_escape_string($con,$sql);
Related
I have the following code:
function dbPublish($status)
{
global $dbcon, $dbtable;
if(isset($_GET['itemId']))
{
$sqlQuery = 'UPDATE ' . $dbtable . ' SET active = ? WHERE id = ?';
$stmt = $dbcon->prepare($sqlQuery);
$stmt->bind_param('ii', $status, $_GET['itemId']);
$stmt->execute();
$stmt->close();
}
}
Do I need to mysql_real_escape_string in this case or am i okay?
No, you don't have to escape value yourself (i.e. no you don't need to call mysqli_real_escape_string), when you are using prepared statements : the DB engine will do that itself.
(Actually, if you were calling mysql_real_escape_string and using bound parameters, your strings would get escaped twice -- which would not be great : you'd end up with escaping characters everywhere...)
As a sidenote : your values are passed as integers (as indicated by the 'ii'), so you wouldn't have to call mysql_real_escape_string, even if you were not using prepared statements : as its name indicates, this function is used to escape... strings.
For integers, I generally just use intval to make sure the data I inject into my SQL queries really are integers.
(But, as you are using prepared queries, once again, you don't have to do that kind of escaping yourself)
No, you must not. Combining the two would result
in visible escape characters showing up in your data.
function dbPublish($status)
{
global $dbcon, $dbtable;
if(isset($_GET['itemId']))
{
$sqlQuery = 'UPDATE ' . $dbtable . ' SET active = ? WHERE id = ?';
$stmt = $dbcon->prepare($sqlQuery);
$stmt->bind_param('ii', $status, $_GET['itemId']);
$stmt->execute();
$stmt->close();
}
}
This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed last year.
I'm trying to make like few text boxes and upon submit another php will be connected let's say it's database.php then the database.php will insert what's in the textboxes into the mysql database table but I'm not sure how I should be into the mysqli_query code....what I have now is
mysqli_query($db,"INSERT INTO jliu VALUE(null,$_GET['title'],$_GET['fname'],$_GET['lname'],$_GET['description'])");
and of course the $_GET won't work properly. I can't really figure how to get it correctly.
You need to break out of the string in order to concatenate it with the $_GET variables.
mysqli_query($db,"INSERT INTO jliu VALUES(null,".$_GET['title'].",".$_GET['fname'].",".$_GET['lname'].",".$_GET['description'].")");
But really you should look into prepared statements to avoid the gaping SQL injection security hole above.
With prepared statements you would be binding the $_GET variables to the parameters in the query.
$stmt = mysqli_prepare($db,"INSERT INTO jliu VALUES(null, ?, ?, ?, ?");
mysqli_stmt_bind_param($stmt, "s", $_GET['title']);
...
// and the same for the others
There's some more detail in the linked manual page on how to execute the prepared statement and return the result.
Please don't use mysql_query() and consorts, they are way too unsafe. Do have a look at PDO and use that instead. Specifically PDO::prepare() and PDOStatement::execute() will be your solution.
Your actual issue, inserting index values of an array into a string can be solved in two ways (more if you count heredoc, sprintf and whatnot):
Use curly braces:
"INSERT INTO jliu VALUE(null, {$_GET['title']}, {$_GET['fname']}, {$_GET['lname']}, {$_GET['description']})"
Use concatenation:
"INSERT INTO jliu VALUE(null, " . $_GET['title'] . ", " . $_GET['fname'] . ", " . $_GET['lname'] . ", " . $_GET['description'] . ")"
However, the overriding issue is that you shouldn't be doing this. With your code, you're wide open to SQL Injection vulnerabilities.
Use prepared statements, and insert your values in there. This creates a more secure (and marginally more performant) query, as you're only binding the values, and not changing the actual query itself. Code example:
if ($stmt = $mysqli->prepare("INSERT INTO jliu VALUES (NULL, ?, ?, ?, ?)")) {
$stmt->bind_param("ssss", $_GET['title'], $_GET['fname'], $_GET['lname'], $_GET['description']);
$stmt->execute();
}
You have to use a prepared statement and replace the variables with a placeholder.
http://php.net/manual/de/mysqli.prepare.php
Answering your question:
You may do something like below. Actually, that is to put a variable of array item into a string, not only for $_GET. Any array may be accessed like that:
$str = "some text {$_GET['title']}"
Or similar approach when you are working with objects:
$str = "some text {$obj->test}"
But, that is bad idea when you are working with sql queries. You should use some functions to clear your input in order to prevent sql injections.
The most stratiforward way is to use mysqli_real_escape_string:
$str = "some text " . mysqli_real_escape_string($_GET['title'])." ...";
Or you can use prepared statements which are more flexible
try this..
$title = mysqli_real_escape_string($_GET['title']);
$fname = mysqli_real_escape_string($_GET['fname']);
$lname = mysqli_real_escape_string($_GET['lname']);
$description = mysqli_real_escape_string($_GET['description']);
$stmt = mysqli_prepare($db,"INSERT INTO jliu VALUES(null,'".$title."','".$fname."','".$lname."','".$description."'");
mysqli_stmt_execute($stmt);
It should be like this.
$query = sprintf("INSERT INTO jliu VALUE(null,%s,%s,%s,%s)",$_GET['title'],$_GET['fname'],$_GET['lname'],$_GET['description']);
mysqli_query($db,$query);
I'm new to sql and PHP. So far have been able to figure things out but the PREPARE statement is giving me syntax issues (maybe because I'm trying to do several things in one step). If someone could let me know where my syntax is messing up that would be great.
In addition the code I'm writing is trying to update save files on a server and while I believe doing it with a prepare statement is the correct way I would be happy to hear if it is not. Note I plan to change INSERT INTO -> a conditional insert or update.
The error I get is unexpected T_STRING. I've marked the line of the error in the code.
$sql='PREPARE statement FROM "INSERT INTO buildings VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) WHERE id="$id" AND ind="$i""';
$result=mysql_query($sql);
for($i=0;$i<1600;$i+=1){
if(isset($_POST['ind'.$i])){
$bind=$_POST['bind'.$i];
$time=$_POST['time'.$i];
$level=$_POST['level'.$i];
$p1ind=$_POST['p1ind'.$i];
$p1state=$_POST['p1state'.$i];
$p1time=$_POST['p1time'.$i];
$p2ind=$_POST['p2ind'.$i];
$p2state=$_POST['p2state'.$i];
$p2time=$_POST['p2time'.$i];
$p3ind=$_POST['p3ind'.$i];
$p3state=$_POST['p3state'.$i];
$p3time=$_POST['p3time'.$i];
$p4ind=$_POST['p4ind'.$i];
$p4state=$_POST['p4state'.$i];
$p4time=$_POST['p4time'.$i];
$p5ind=$_POST['p5ind'.$i];
$p5state=$_POST['p5state'.$i];
$p5time=$_POST['p5time'.$i];
$sql = 'SET #bind="$bind",'. //<-line of error
'#time="$time",'.
'#level="$level",'.
'#p1ind="$p1ind",'.
'#p1state="$p1state",'.
'#p1time="$p1time",'.
'#p2ind="$p2ind",'.
'#p2state="$p2state",'.
'#p2time="$p2time",'.
'#p3ind="$p3ind",'.
'#p3state="$p3state",'.
'#p3time="$p3time",'.
'#p4ind="$p4ind",'.
'#p4state="$p4state",'.
'#p4time="$p4time",'.
'#p5ind="$p5ind",'.
'#p5state="$p5state",'.
'#p5time="$p5time",'.
'#id="$id",'.
'#ind="$i"';
$result=mysql_query($sql);
$sql='EXECUTE statement USING #id,#time,#level,#p1ind,#p1state,#p1time,#p2ind,#p2state,#p2time,#p3ind,#p3state,#p3time,#p4ind,#p4state,#p4time,
#p5ind,#p5state,#p5time,#ind,#bind';
$result=mysql_query($sql);
if(!$result){
die("saveArry[0]=".mysql_error().";");
}else{
die("saveArry[0]='saved';");
}
}
}
$sql='DEALLOCA PREPARE statement';
$result=mysql_query($sql);
Update I am unable to install PDO on my hosts servers and therefore PDO is unfortunately an unacceptable solution. My answer (now with no errors!):
if(isset($_POST['ind'])){
$ind=sanitizeString($_POST['ind']);
$bind=sanitizeString($_POST['bind']);
$time=sanitizeString($_POST['time']);
$level=sanitizeString($_POST['level']);
$p1ind=sanitizeString($_POST['p1ind']);
$p1state=sanitizeString($_POST['p1state']);
$p1time=sanitizeString($_POST['p1time']);
$p2ind=sanitizeString($_POST['p2ind']);
$p2state=sanitizeString($_POST['p2state']);
$p2time=sanitizeString($_POST['p2time']);
$p3ind=sanitizeString($_POST['p3ind']);
$p3state=sanitizeString($_POST['p3state']);
$p3time=sanitizeString($_POST['p3time']);
$p4ind=sanitizeString($_POST['p4ind']);
$p4state=sanitizeString($_POST['p4state']);
$p4time=sanitizeString($_POST['p4time']);
$p5ind=sanitizeString($_POST['p5ind']);
$p5state=sanitizeString($_POST['p5state']);
$p5time=sanitizeString($_POST['p5time']);
$rot=sanitizeString($_POST['rot']);
$sql="INSERT INTO buildings (id,ind,bind,time,level,p1ind,p1state,p1time,p2ind,p2state,p2time,p3ind,p3state,p3time,p4ind,p4state,p4time,p5ind,
p5state,p5time,rot) VALUES ('$id','$ind','$bind','$time','$level','$p1ind','$p1state','$p1time','$p2ind','$p2state','$p2time','$p3ind','$p3state',
'$p3time','$p4ind','$p4state','$p4time','$p5ind','$p5state','$p5time','$rot') ON DUPLICATE KEY UPDATE bind='$bind',time='$time',level='$level',
p1ind='$p1ind',p1state='$p1state',p1time='$p1time',p2ind='$p2ind',p2state='$p2state',p2time='$p2time',p3ind='$p3ind',p3state='$p3state',
p3time='$p3time',p4ind='$p4ind',p4state='$p4state',p4time='$p4time',p5ind='$p5ind',p5state='$p5state',p5time='$p5time',rot='$rot'";
$result=mysql_query($sql);
if(!$result){
die("saveArry[0]=".mysql_error().";");
}else{
die("saveArry[0]=saved;");
}
}
The single and double quotes are interchanged in that line, should be,
$sql = "SET #bind='$bind',
#time='$time',
#level='$level',
#p1ind='$p1ind',
#p1state='$p1state',
#p1time='$p1time',
#p2ind='$p2ind',
#p2state='$p2state',
#p2time='$p2time',
#p3ind='$p3ind',
#p3state='$p3state',
#p3time='$p3time',
#p4ind='$p4ind',
#p4state='$p4state',
#p4time='$p4time',
#p5ind='$p5ind',
#p5state='$p5state',
#p5time='$p5time',
#id='$id',
#ind='$i'";
I strongly recommend using PDO instead of deprecated mysql_* functions. It is doing the hard work with prepared statements for you transparently.
As EthanB pointed out in comment, your code is vulnerable to SQL injection as you are inserting the values directly from user input ($_POST variable).
With PDO your code would look something like this (simplified):
$statement = $pdo->prepare("INSERT INTO buildings VALUES(:ind, :bind, :time, :level, ...) WHERE id = :id AND ind = :ind");
for( ... ) {
$statement->execute(array(
":ind" => $_POST["ind" . $i],
":bind" => $_POST["bind" . $i], ...
));
}
The PDO will send the PREPARE and EXECUTE queries for you and escape all parameters to prevent SQL injection.
So in this program I'm writing, I actually grab a SQL query from the user using a form. I then go on to run that query on my database.
I know not to "trust" user input, so I want to do sanitization on the input. I'm trying to use mysql_real_escape_string but have been unsuccessful in getting it to work.
Here's what I'm trying, given the input:
select * from Actor;
//"query" is the input string:
$clean_string = mysql_real_escape_string($query, $db_connection);
$rs = mysql_query($clean_string, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
This is ALWAYS giving me the
"Invalid input!"
error.
When I take out the clean_string part and just run mysql_query on query, the
"invalid
input"
message is not output. Rather, when I do this:
$rs = mysql_query($query, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
It does NOT output
"invalid input".
However, I need to use the mysql_real_escape_string function. What am I doing wrong?
Update:
Given
select * from Actor; as an input, I've found the following.
Using echo statements I've
found that before sanitizing, the string holds the value:
select * from Actor;
which is correct. However, after sanitizing it holds the incorrect
value of select *\r\nfrom Actor;, hence the error message. Why is
mysql_real_escape_string doing this?
use it on the actual values in your query, not the whole query string itself.
example:
$username = mysql_real_escape_string($_POST['username']);
$query = "update table set username='$username' ...";
$rs = mysql_query($query);
Rather than using the outdated mysql extension, switch to PDO. Prepared statement parameters aren't vulnerable to injection because they keep values separate from statements. Prepared statements and PDO have other advantages, including performance, ease of use and additional features. If you need a tutorial, try "Writing MySQL Scripts with PHP and PDO".
mysql_real_escape_string() is the string escaping function. It does not make any input safe, just string values, not for use with LIKE clauses, and integers need to be handled differently still.
An easier and more universal example might be:
$post = array_map("mysql_real_escape_string", $_POST);
// cleans all input variables at once
mysql_query("SELECT * FROM tbl WHERE id='$post[id]'
OR name='$post[name]' OR mtime<'$post[mtime]' ");
// uses escaped $post rather than the raw $_POST variables
Note how each variable must still be enclosed by ' single quotes for SQL strings. (Otherwise the escaping would be pointless.)
You should use mysql_real_escape_string to escape the parameters to the query, not the entire query itself.
For example, let's say you have two variables you received from a form. Then, your code would look like this:
$Query = sprintf(
'INSERT INTO SomeTable VALUES("%s", "%s")',
mysql_real_escape_string($_POST['a'], $DBConnection),
mysql_real_escape_string($_POST['b'], $DBConnection)
);
$Result = mysql_query($Query, $DBConnection);
manual mysql_real_escape_string()
Escapes special characters in a string
for use in an SQL statement
So you can't escape entire query, just data... because it will escape all unsafe characters like quotes (valid parts of query).
If you try something like that (to escape entire query)
echo mysql_real_escape_string("INSERT INTO some_table VALUES ('xyz', 'abc', '123');");
Output is
INSERT INTO some_table VALUES (\'xyz\',
\'abc\', \'123\');
and that is not valid query any more.
This worked for me. dwolf (wtec.co)
<?php
// add data to db
require_once('../admin/connect.php');
$mysqli = new mysqli($servername, $username, $password, $dbname);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$post = $mysqli->real_escape_string($_POST['name']);
$title = $mysqli->real_escape_string($_POST['message']);
/* this query with escaped $post,$title will work */
if ($mysqli->query("INSERT into press (title, post) VALUES ('$post', '$title')")) {
printf("%d Row inserted.\n", $mysqli->affected_rows);
}
$mysqli->close();
//header("location:../admin");
?>
So in this program I'm writing, I actually grab a SQL query from the user using a form. I then go on to run that query on my database.
I know not to "trust" user input, so I want to do sanitization on the input. I'm trying to use mysql_real_escape_string but have been unsuccessful in getting it to work.
Here's what I'm trying, given the input:
select * from Actor;
//"query" is the input string:
$clean_string = mysql_real_escape_string($query, $db_connection);
$rs = mysql_query($clean_string, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
This is ALWAYS giving me the
"Invalid input!"
error.
When I take out the clean_string part and just run mysql_query on query, the
"invalid
input"
message is not output. Rather, when I do this:
$rs = mysql_query($query, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
It does NOT output
"invalid input".
However, I need to use the mysql_real_escape_string function. What am I doing wrong?
Update:
Given
select * from Actor; as an input, I've found the following.
Using echo statements I've
found that before sanitizing, the string holds the value:
select * from Actor;
which is correct. However, after sanitizing it holds the incorrect
value of select *\r\nfrom Actor;, hence the error message. Why is
mysql_real_escape_string doing this?
use it on the actual values in your query, not the whole query string itself.
example:
$username = mysql_real_escape_string($_POST['username']);
$query = "update table set username='$username' ...";
$rs = mysql_query($query);
Rather than using the outdated mysql extension, switch to PDO. Prepared statement parameters aren't vulnerable to injection because they keep values separate from statements. Prepared statements and PDO have other advantages, including performance, ease of use and additional features. If you need a tutorial, try "Writing MySQL Scripts with PHP and PDO".
mysql_real_escape_string() is the string escaping function. It does not make any input safe, just string values, not for use with LIKE clauses, and integers need to be handled differently still.
An easier and more universal example might be:
$post = array_map("mysql_real_escape_string", $_POST);
// cleans all input variables at once
mysql_query("SELECT * FROM tbl WHERE id='$post[id]'
OR name='$post[name]' OR mtime<'$post[mtime]' ");
// uses escaped $post rather than the raw $_POST variables
Note how each variable must still be enclosed by ' single quotes for SQL strings. (Otherwise the escaping would be pointless.)
You should use mysql_real_escape_string to escape the parameters to the query, not the entire query itself.
For example, let's say you have two variables you received from a form. Then, your code would look like this:
$Query = sprintf(
'INSERT INTO SomeTable VALUES("%s", "%s")',
mysql_real_escape_string($_POST['a'], $DBConnection),
mysql_real_escape_string($_POST['b'], $DBConnection)
);
$Result = mysql_query($Query, $DBConnection);
manual mysql_real_escape_string()
Escapes special characters in a string
for use in an SQL statement
So you can't escape entire query, just data... because it will escape all unsafe characters like quotes (valid parts of query).
If you try something like that (to escape entire query)
echo mysql_real_escape_string("INSERT INTO some_table VALUES ('xyz', 'abc', '123');");
Output is
INSERT INTO some_table VALUES (\'xyz\',
\'abc\', \'123\');
and that is not valid query any more.
This worked for me. dwolf (wtec.co)
<?php
// add data to db
require_once('../admin/connect.php');
$mysqli = new mysqli($servername, $username, $password, $dbname);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$post = $mysqli->real_escape_string($_POST['name']);
$title = $mysqli->real_escape_string($_POST['message']);
/* this query with escaped $post,$title will work */
if ($mysqli->query("INSERT into press (title, post) VALUES ('$post', '$title')")) {
printf("%d Row inserted.\n", $mysqli->affected_rows);
}
$mysqli->close();
//header("location:../admin");
?>