mysqli insert error incorrect syntax [duplicate] - php

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 3 years ago.
I know a lot of people have the same error occasionally however I have looked at all previous answers and my code and i have tried col with and without backticks
Here is my current code
I also have tried with $var as well as just $var but same
if(!empty($_POST['email'])){
$date = date('dmY'); #Todays Date
$ip = str_replace('.','',$_SERVER['REMOTE_ADDR']); #Visitor IP
$verify = md5($date.$ip); #MD5 ENCRYPT THE 2 VALUES
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$email = $_POST['email'];
$password = md5($_POST['password']);
$link = mysqli_connect($dbh,$dbu, $dbp, $dbn);
$query = mysqli_query($link, "INSERT INTO `users` (`email`,`fname`,`lname`,`verify`,`password`,`joined`)
VALUES($email,$fname,$lname,$verify,$password,$date)");
if($query){
echo "inserted";
}
else {
echo mysqli_error($link);
}
There are other columns in the table however its only the above columns I want to add data for the rest can use default values initially
I've been looking at this code for so long now I just cant spot my problem, I know its something silly

The most mistake-proof way to add a variable into an SQL query is to add it through a prepared statement.
So, for every query you run, if at least one variable is going to be used, you have to substitute it with a placeholder, then prepare your query, and then execute it, passing variables separately.
First of all, you have to alter your query, adding placeholders in place of variables. Your query will become:
$sql = "INSERT INTO users (fname, lname) VALUES (?, ?)";
Then, you will have to prepare it, bind variables, and execute:
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "ss", $fname, $lname);
mysqli_stmt_execute($stmt);
As you can see, it's just three simple commands:
prepare() where you send a query with placeholders
bind_param where you send a string with types ("s" is for string and you can use it for any type actually) and than actual variables.
and execute()
This way, you can always be sure that not a single SQL syntax error can be caused by the data you added to the query! As a bonus, this code is bullet-proof against SQL injection too!
It is very important to understand that simply adding quotes around a variable is not enough and will eventually lead to innumerable problems, from syntax errors to SQL injections. On the other hand, due to the very nature of prepared statements, it's a bullet-proof solution that makes it impossible to introduce any problem through a data variable.

Related

PHP MySQL prepared statement: procedural Insert / update example [duplicate]

This question already has answers here:
How to use mysqli prepared statements?
(3 answers)
Closed 11 months ago.
I struggle to understand prepared statements in PHP to allow users to edit a MySQL-database.
The user input is UTF-8, typical examples are the name in Arabic, Chinese, ... It also generates a problem when using Geo-location as 47°23'15"N, 4°12°27"E, as is visible i.e. in Wikipedia.
Best lead I found to my problem to insert, insert ignore, on duplicate key ... to update datasets in a database from user-input using prepared statements. An interesting lead is in PHP Insert Prepared Statement, but that's "PDO", which I happen to lack any experience with.
So far I tried to sanitize, now it seems to me that it might be far easier and safer to use prepared statements. But. I'm bloody amateur. And use procedural statements. And never tried a prepared statement before. And the input expects better understanding.
So I would like to take something like
<?php
$name = $_POST['name'];
$user = filter_var($_POST['user'], FILTER_SANITIZE_EMAIL);
$descr = $_POST['utf8text'];
$geo = $_POST['geo']; // See [1] below.
?>
[1] Which is i.e. 47°23'15"N, 4°12'27"E and I am not sure how to properly escape it? filter_var($_POST['geo'],FILTER_SANITIZE_ADD_SLASHES) returns 47°23\'15\"N, 4°12\'27\"E?
Then to enter this into an SQL database like traditional
<?php
$link = mysqli_connect('localhost', 'user', 'pass','database');
mysqli_set_charset($link,'utf8');
$insertsql = "INSERT INTO `database` (`name`,`user`,`descr`, geo)
VALUES ('". $name . "', '" . $user . "', '" . $descr . "', " . $geo . "')
ON DUPLICATE KEY UPDATE `descr`='" . $descr . "', '" . $geo . "';
mysqli_query($link,$insertsql);
?>
Okayokay, using added code to make sure the database connection works, the query is processed properly and failure handling. But I want to simplify.
My question would be, how I would prepare such group of values for a prepared statement. And I believe to understand I must replace mysqli_query with mysqli_prepare and I need a count of the fields addressed and use "ssss" but don't find any explanation in any of the manuals what the s's (multiple "s") do.
What I tried didn't work (yet) and I need a working example to understand what I have to do. I tried to adjust the example in above linked article without PDO to no success.
And I am worried if/how the prepared data is transferred in strings when using ON DUPLICATE KEY, as I don't find any explanation there either (PEBKAS?).
Any help appreciated!
If I understood correctly, you want to make a mysql prepared query?
(I apologize if I misunderstood the problem)
But here my solution and explanation. First :
$stmt = mysqli_prepare($link, "INSERT INTO `database` (`name`,`user`,`descr`, geo) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE descr= ?, ?;");
Here $link is your mysqli_connect
You set ? where you want to put your future variables
mysqli_stmt_bind_param($stmt, 'ssssss', $name, $user, $descr, $geo, $descr, $geo);
All ? need to be defenied what types of variable it's gonna be, here it's gonna be a string so we set S (You can find the others possibilities for the second parameter here)
Then all ? will be bound to your variables in the order in which you want it to appear instead of ?
mysqli_stmt_execute($stmt)
And finally you execute the query

SQL Query works without WHERE, but once I add WHERE statement, it is not running properly [duplicate]

This question already has answers here:
Can I mix MySQL APIs in PHP?
(4 answers)
Closed 4 years ago.
There is an SQL query I am writing which executes fine when written as below, but it updates all rows.
mysqli_query($connection, 'UPDATE users SET hashed_pass = ' . mysql_escape($newpassword).'');
However, as soon as I attempt to add some logic to it by adding a WHERE statement, I don't get any errors but it is not updating the password for the intended user. I want the statement to update, in this case, user 569 (which is what $user_id is equal to).
mysqli_query($connection, 'UPDATE users SET hashed_pass = ' . mysql_escape($newpassword).' WHERE user_id ='.mysql_escape($user_id).'');
The mysql_escape function just strips slashes and escapes the variable so I know that is not the cause. I also made sure that the table does in fact have the user_id column and the variable $user_id is 569, which matches the user I want to update. After I run the command I don't get any errors and I have an echo statement under the query to confirm that it ran.
Any ideas what I am doing wrong?
Update:
As everyone suggested I, converted my code to a prepared statement and it is now working.
$stmt = mysqli_prepare($connection, "UPDATE users SET hashed_pass = ? WHERE user_id = ?");
mysqli_stmt_bind_param($stmt, "si", $newpassword, $user_id);
mysqli_stmt_execute($stmt);
Use prepared statements would be the first step. PHP mysqli_prepare
$stmt = mysqli_prepare($connection, "UPDATE users SET hashed_pass = ?")
mysqli_stmt_bind_param($stmt, "s", $citynewpassword);
mysqli_stmt_execute($stmt);

Difference between real_escape_string and prepare()? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
prepare() seems a bit tedious and unnecessary for a majority of my code. If I send a string in a SQL command, why can't I just sanitize it with real_escape_string? What's the difference? That's what I've been doing all the time and it worked well against SQL injections... Thanks.
Escaping is just as effective at SQL injection defense as using query parameters.
Both methods are also less effective if you fail to do them consistently.
Both methods are useful only for protecting individual values in SQL expressions. They don't support other dynamic parts of the query. For example, if you want to ORDER BY a user-specified column. Neither query parameters nor escaping functions handle that.
So basically, it is a matter of style and personal preference.
I prefer query parameters because I think this:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$a, $b, $c]);
Is more clear than this:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES ('".mysqli_real_escape_string($conn, $a)."', '".mysqli_real_escape_string($conn, $b)."', '".mysqli_real_escape_string($conn, $c)."')";
mysqli_query($conn, $sql);
You can't seriously be saying that fiddling with all those open-quotes/close-quotes and . string concatenation is easier than using prepare() with query parameters.
Re your comments about a hypothetical query() function with parameters.
First of all, it's not necessary. Using prepare() and execute() together is a small price to pay for writing secure code, and by insisting on doing it with a single function, you just sound lazy. I suppose you don't check the return value of functions that return false on error, either?
For what it's worth, it'd be easy to write a wrapper function to do both, because PHP supports varargs implicitly.
function myquery() {
global $pdo;
$params = func_get_args();
$sql = array_shift($params);
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return $stmt; // so we can fetch(), etc.
}

Apostrophy and quotation marks won't add to mysql from a form

I need some help here!
I have a form on a site admin page, the owner fills in his projects and the get added to a mysql db, but sometimes the data contains single or double quotes so it won't add to the db.
I tried using addslashes but it still wont work.
Heres my code which Ive tried
$atitle = addslashes($_REQUEST['atitle']);
$acontent = addslashes($_REQUEST['acontent']);
$query = "INSERT INTO projects VALUES (NULL, '$atitle', '$acontent', '$remote_file', '$remote_file1', '$remote_file2')";
$result = mysql_query($query);
if(!$result){
$error = 'An error occured: '. mysql_error().'<br />';
$error.= 'Query was: '.$query;
echo $error;
die($message);
}
Can anyone help me with this?
mysql_query is part of an outdated php library that isn't supported anymore. The more reliable method of interacting with a database is mysqli. Using mysqli, you'll be able to use Prepared Statements. Prepared Statements are a way to validate input and to mitigate problems like this (your input having quotation ticks/marks). Take a look at this example:
$db = new mysqli("host","user","pw","database");
$stmt = $db->prepare("INSERT INTO projects VALUES (NULL, '?', '?', '?', '?','?')");
$stmt->bind_param('s', $atitle); // s means string in the first param
$stmt->bind_param('s', $acontent); // s means string in the first param
... // same for all other parameters in your query
$stmt->execute();
More on this: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
I heavily recommend using mysqli. It is current and supported. Prepared Statements are the best way to defend against SQL injections and also catching trip-ups like this. It will sanitize the input for you and account for quotation symbols.
you can try stripslashes() to un-quotes a quoted string. More details are available on the PHP documentation website here.

Is this a good way to sanatize php $_POST inputs? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I have been using this code on my website for a long time, and just want to make sure I am correctly sanatizing my PHP $_POST inputs...
foreach($_POST as $key=>$val) //this code will sanitize your inputs.
$_POST[$key] = mysqli_real_escape_string($connection, $val);
Say for example I had the POST value $_POST['comment'] that I wanted to add to a database, would this be a good and safe way to sanatize it before database entry?
foreach($_POST as $key=>$val) //this code will sanitize your inputs.
$_POST[$key] = mysqli_real_escape_string($connection, $val);
//is this safe? or is there another step?
$comment = $_POST['comment'];
if($comment != ""){
//add $comment to database
}
Is there something that I still need to do before adding $comment to the MYSQL database? Or do those top two lines do the magic by themselves? Please let me know if this is a good safe way to do it, or if there is an even better way! Thanks!
Possible duplicate of: https://stackoverflow.com/questions/15664021/php-escaping-vars-posted-through-var-and-got-by-postvari-with-a-meth
I already tried your way. It seems there's no magic function. However, from classic MySQL injections, you can be safe, when adding mysqli_real_escape_string to each posted value, then use it as a string (quoted) in the db, but it's considered bad practice, also is not the most secure way
Since MySQLi presents parametised queries, you should get familiar with them, and leave the real corresponding to the database driver, to the library.
It's not. One can use multibyte attacks, which will bypass all these sanitizers.
Moreover,
According to this answer one should avoid writing to post so one can keep sanitized code far from un-sanitized. Even though you "sanitize" everything, it leads to bad habits.
This is not a good way to sanitize input. Queries should be parameterized and input should be fed as arguments no matter where it comes from. No additional sanitation should be done (otherwise it could be duplicated).
If you have specific rules (such as $comment != "") this is validation, and it is up to you to decide validation rules and how to handle invalid input (which is different than unsanitized input).
Example of using properly parameterized prepared statement with mysqli:
$stmt = mysqli_prepare($connection, "INSERT INTO comments VALUES (?)");
mysqli_stmt_bind_param($stmt "s", $comment);
mysqli_execute($stmt);
_real_escape_string does not sanitize user inputs completely. You must use prepared statements.
Object oriented style
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
Procedural style
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
Parameter types
Character Description
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
Documentation
down side is that you maim the post vars so you cant use them for other purposes than queries. for example what if you still wanted to echo out some post vars?
better is to escape to a new array
and even better is to not escaped but use parameterized queries.
Your missing some of the most important things to safe PHP coding.
Lets start from the beginning.
Start with these links please : Please read the code comments
This first // and this second!
1) Validate and then filter your data if it passes validation!
So we have a registration form, one that takes emails... so now what we do is validate the email.
$email = $_POST['email']; // Declare the variable
if (filter_var($email, FILTER_VALIDATE_EMAIL)) { // If validation passes ...
$safe_email = filter_var($email, FILTER_SANITIZE_EMAIL) // Sanitize the email
} else { // Validation fails no need to sanitize
echo "WRONG EMAIL PUNK!!!!";
}
2) Now using either Mysqli or PDO (I prefer PDO) we do :
$dbh = new PDO("mysql:host=xxxxxx;dbname=xxxxxx;charset=utf8", USERNAME(XXXXXXXXX), PASSWORD(XXXXXXXX); // Set up the PDO instance PLEASE DO NOT FORGET TO EXPLICETELY STATE A CHARSET!!!!
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set up error mode
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); // I prefer emulate prepares to be false
$sql = INSERT INTO ..... (........., email) VALUES (............, :email); // Set up our named parameter
$query -> $dbh -> prepare($sql); // Prepare the query
$query -> bindParam (':email', $email);
$query -> execute() // Yay!
Its all fine and dandy using PDO and MysqlI but there is an expression called :
Its not the wand, its the wizard.
PDO / MysqlI can not solve everything! Make sure to
Refer to my other question on how to set up PDO
1) Validate
2) Sanitize
3) use parameters for safer queries!
4) Escape any outside (un-trusted data)
Follow these security PHP practices for safer php coding.
Enjoy

Categories