Passing one literal variable as well as placeholders in prepared statement? [closed] - php

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am creating a form that will be submitted by the user. In the form submission process, some values are hardcoded in the source code and are inserted as it is. Can I pass these values directly to the prepared statement? Other user input data I am binding that will be replaced with the ? placeholder.
For example:
...
$litVariable = 1;
$userInput = $_POST['user_input'];
$myquery = $mysqli->prepare("INSERT INTO table(`column1`,`column2`) VALUES('$litVariable',?)");
$myquery->bind_param("s",$user_input);
...
Is that ok and safe to pass $litVariable directly to query and user-generated input with $myquery->bind_param("s",$user_input);, as I did above?

Yes, what you are doing should be safe, because the value $litVariable which you are concatenating into the query string does not come from the outside. This means that the first item in your VALUES clause should not be prone to injection attacks coming from the outside. That being said, I would still suggest not even doing this, because it leaves your insert query looking prone to attack. There is no reason to not use bound parameters everywhere. That is, I suggest the following:
$litVariable = 1;
$userInput = $_POST['user_input'];
$sql = "INSERT INTO table(column1, column2) VALUES (?, ?)";
$myquery = $mysqli->prepare(sql)
$myquery->bind_param("is", $litVariable, $user_input);

This question is more about psychology than technology.
When your processing is uniform, you don't have to measure every single variable you are working with, considering whether it is secure or not. You will get in return
faster coding. you don't have to stop and think, how this particular variable is going to be inserted - as is or prepared. For the every single variable.
no chance for the human error when you can swear that a variable is safe but in reality it is not
To soften the pill, I can offer you a mysqli helper function that can make your prepared queries less boring
$sql = "INSERT INTO table(column1, column2) VALUES (?, ?)";
prepared_query($mysqli, $sql, [$litVariable, $userInput]);
only two lines of meaningful code versus four lines of repetitive code.

Related

How to update an SQL database with form data using PHP? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
How do I get html form POST data to appear after the = signs?
$tsql = "UPDATE dbo.[order]
SET status=''
WHERE order_ID='' ";
All POST data is stored in $_POST
put $_POST['dataname'] there.
SET status='".$_POST['dataname']."'
would be the proper replacement.
POST data can be retrieved using the $_POST suberglobal like this:
.... " SET status = '{$_POST['form_field_name']}'";
HOWEVER, I would recommend using prepared statements for this whenever possible. Putting form data directly into an SQL statement is a bad practice and can cause security issues.
You should use a prepared statement like this:
// Store the form data in variables
$status = $_POST['status_field'];
$order_ID = $_POST['order_ID_field'];
// If you're not going to use prepared statements AT LEAST do this
// Not a necessary step if using prepared statements
$sanitized_status = mysqli_real_escape_string($dbConnection, $status);
$sanitized_order_ID = mysqli_real_escape_string($dbConnection, $order_ID);
// Prepare the SQL
// When script is run database will compile this statement first
$stmt = $dbConnection->prepare('UPDATE table_name SET status = ? WHERE order_ID = ?');
// Parameters are bound to the COMPILED statement not the string
$stmt->bind_param('si', $sanitized_status, $sanitized_order_ID);
$stmt->execute();
The key is to bind your form data to the compiled statement and not the SQL string itself. Read more about prepared statements in this excellent resource below!
Reference: How can I prevent SQL injection in PHP?

PHP mysql query insert where [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm trying to confirm a users email where the users verification key is the variable $verify_mod. However, I get the error,
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 'WHERE verification='72b4ad7ee82dd6e177f2588c168abb51user=test123'' at line 1
Here's my query:
$confirm_query = "INSERT INTO users (confirm_email) VALUES ('1') WHERE verification='$verify_mod'";
The INSERT statement doesn't go with a WHERE clause. Either you're trying to insert something, in which case you should remove the WHERE clause, or you want to modify a value, in which case you should use UPDATE .. SET.
// For an insert:
$confirm_query = "INSERT INTO users (confirm_email) VALUES ('1')";
// For an update:
$confirm_query = "UPDATE users SET confirm_email='1' WHERE verification='$verify_mod'";
Besides that, it's always a good idea to put ` characters around table and column names to reduce the risk of SQL injection. So:
// For an insert:
$confirm_query = "INSERT INTO `users` (`confirm_email`) VALUES ('1')";
// For an update:
$confirm_query = "UPDATE `users` SET `confirm_email`='1' WHERE `verification`='$verify_mod'";
Lastly, I don't know if you're using mysqli_* functions or PDO or mysql_* functions (in the latter case you should definitely change to one of the others as mysql_* is deprecated). In any of the first two cases you should use parameterized queries or prepared statements. You prepare the query and then fill in the variables ($verify_mod here). That way, the variables get escaped properly, again, to reduce the risk of SQL injection.
You are doing an insert, this sounds like it should be an update statement though (you can't do where in inserts either as it doesn't make sense to):
$confirm_query = "UPDATE users set confirm_email=1 WHERE verification='$verify_mod'"
Extending upon #CamilStaps answer, here's how you can parameterize your query using mysqli.
// For an insert: (No need to bind parameters for this one)
$confirm_query = $mysqli->prepare("INSERT INTO `users` (`confirm_email`) VALUES ('1')");
$confirm_query->execute();
// For an update:
$confirm_query = $mysqli->prepare("UPDATE `users` SET `confirm_email`='1' WHERE `verification`= ? ");
$confirm_query->bind_param('s', $verify_mod);
$confirm_query->execute();

INSERT into sql database [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've inserted into databases before but never used the 'where' feature. For some reason, it is not inserting, but dieing instead.
<?php
$member=$_SESSION['member'];
$SQL = "INSERT into members where name='$member'(money) VALUES ('100')";
mysql_query($SQL) or die("Could not insert money");
print "Money successfully inserted";
?>
This is not valid SQL:
INSERT into members where name='$member'(money) VALUES ('100')
I would assume something like this:
update `members` set `money`=100 where `name`='$member';
Rationale: (money) is a field and 100 is the value for money (since those 2 make the most sense from a INSERT INTO members (field) VALUES (value) syntax point of view).
Never die() with a fixed error message, especially when you can output the actual reason: ... or die(mysql_error()).
But yes, your problem is a syntax error. INSERT queries do NOT have a WHERE clause - where is used to filter records already in the database table. This makes no sense for a new record, because it's not IN the table to filtered in the first place.
You query should basically be just
INSERT into members (name, money) VALUES ('$member', '100')
And note that you are vulnerable to SQL injection attacks, and are using a deprecated/obsolete database interface.
If you want to change existing data, use the update command instead of insert.
You can't use WHERE clause with INSERT command
http://dev.mysql.com/doc/refman/5.0/en/insert.html
You have to do an update
<?php
$member=$_SESSION['member'];
$SQL = "UPDATE `members` SET `money`='100' WHERE `name`='$member'; ";
mysql_query($SQL) or die("Could not insert money");
print "Money successfully inserted";
?>
For inserting :
$SQL = "INSERT INTO members(money) VALUES ('100')";
MySQL INSERT Syntax does not support the WHERE clause. MySQL.com Insert Info
Are you actually trying to insert a new row, or update an existing 'member'? If update, then try:
UPDATE members SET money = 100, WHERE name='$member';

Is this code safe against mysql injections? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
$stmt_update = $db->prepare("UPDATE 2_1_journal SET RecordDay = ?, WHERE Number = ? ");
$stmt->execute(array($amount1, $date_day1));
Is this safe against mysql injections?
If safe, as I understand it is because of "= ?". Then question how "= ?" works/helps
Question is because here http://php.net/manual/en/pdo.prepare.php is written
Prepared statements only project you from SQL injection IF you use the bindParam or bindValue option.
For example if you have a table called users with two fields, username and email and someone updates their username you might run
UPDATE `users` SET `user`='$var'
where $var would be the user submitted text.
Now if you did
<?php
$a=new PDO("mysql:host=localhost;dbname=database;","root","");
$b=$a->prepare("UPDATE `users` SET user='$var'");
$b->execute();
?>
and the user had entered User', email='test for a test the injection would occur and the email would be updated to test as well as the user being updated to User.
In my code (above) there is no bindParams and no bindValue. So do not know if it is safe and if yes, then what part of code ensures it. Please, advice
Update
After reading this How can I prevent SQL injection in PHP? have got one more question
Does this code
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->execute(array($name));
the same as this?
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array(':name' => $name));
If yes, then seems it is better to use first code because it is shorter?
Yes, prepared statements are always safe from inject attacks as long as there are no logical flaws, such as using name = '?'.
bindParam is really helpful when you want to bind different datatypes; such as string, integer etc in the query. For eg:
$stmt = $pdo->prepare('SELECT * FROM employees WHERE myID = ?');
$stmt->bindParam( 1, $id, PDO::PARAM_INT );
$stmt->execute();
Prepared statements only project you from SQL injection IF you use the bindParam or bindValue option.
Manual is incorrect here. Passing data into execute() is safe as well. The main thing is using a placeholder to represent the actual data in the query. As long as you're using a placeholder instead of the actual data - you are safe. However, PDO doesn't offer you placeholders for the everything you can add into query, identifiers for example.
Does this code the same as this?
Yes.
Named placeholders are just a "syntax sugar" for a regular ones.
Technically they are the same in either way - so, it's only a matter of taste.
Personally I prefer regular question mark placeholders as they indeed makes the code dramatically shorter, while named placeholders makes it bloated with no benefit.

Mysqli and binding multiple value sets during insert [duplicate]

This question already has answers here:
PHP MySQLi Multiple Inserts
(3 answers)
Closed 3 years ago.
Hoping someone can give me some insight here.
When having to insert multiple rows into a table at once, I've used sql that looks something like this:
INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce')
As you can see I'm inserting three rows with one statement. The reason I do this is that I believe it is more efficient than executing three distinct statements to insert the rows.
So my question is this: how do I do this if I want to be able to bind my values to a statement? Unfortunately I've been looking all over the web and I can only find example of single statements in the form of:
$stmt = $mysqli->prepare("INSERT INTO some_names (firstName, lastName) VALUES (?, ?)");
$stmt->bind_param('ss', $firstName, $lastName);
$firstName = "Joe";
$lastName = "Smith";
$stmt->execute();
$firstName = "Fred";
$lastName = "Sampson";
$stmt->execute();
It seems that this would be the equivalent of doing separate INSERT statements and seems to be less efficient.
So my question is: Is there any way to bind in a multi-insert statement? Please educate me here! Thanks
Simple:
$stmt = $mysqli->prepare("INSERT INTO some_names (firstName, lastName) VALUES (?, ?),(?,?),(?,?)")
$stmt->bind_param('ssssss', 'Joe', 'Smith','Fred','Sampson','Lisa','Pearce');
It seems that this would be the equivalent of doing separate INSERT statements and seems to be less efficient.
No, it’s not less efficient – because a statement is prepared only once (to figure out what it is supposed to do), and after that is done only the data is send to the database afterwards.
You are looking at this the wrong way.
You would pretty much never do what you have shown above, it would almost always be done in a loop. And even if you dynamically constructed (?, ?), (?, ?), (?, ?) you would still have to loop to build the query string and bind the data (which would get even more complicated because of MySQLi's ridiculous insistance on by-ref bindings) so it wouldn't gain you anything in terms of work that needs to be done by PHP - you just moved the loop - and it would lose you a lot in terms of readability.
It does have a gain in round trips to the database (assuming you are always inserting more than one row) - but this would only make a meaningful difference when inserting hundreds or thousands or rows, in which case you are most likely performing some kind of import operation, in which case the extra couple of seconds probably don't matter (it won't be e.g. slowing a page load).

Categories