How to use same query to insert data - php

I am new at programming.
I am trying to create a simple guestbok.
i have one index page where you can register a firstname, lastname and email.
And if you click on one name you redirect to a new page with id.
How can i now insert text to this ID with the same codeblock using the ID.
My code looks like this.
<?php
require('dbconfig.php');
try {
$conn = new PDO("mysql:host=$servername;dbname=projektone", $username, $password);
//Set PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Insert to database
$sql = "INSERT INTO user (firstname, lastname, email)
VALUE ('".$_POST["first_name"]."','".$_POST["last_name"]."','".$_POST["email"]."')";
$sql = "INSERT INTO user (guestbok)
VALUE ('".$_POST["guestbok"]."')";
$conn->query($sql);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
header('Location: /');
?>
Thanks in advance
/Daniel

Joining up raw bits of text and passing them on to your database to process is not a good idea. It opens up your system to SQL injection. While it's unlikely that someone could compromise your site when only INSERT statements are exposed in this way, it does mean that:
anyone with an apostrophe in their name will break the logic of the request
you are exposing a method by which someone can carry out a stored XSS attack by submitting javascript to your guestbook
Regarding the SQL Injection problem, there are 2 methods to protect your system - one is to transform the data in which a way that it cannot break the SQL string it is added to (e.g. using mysqli_real_escape_string()) but the recommended approach when using PDO to mediate your code's interaction with the DBMS is to use variable binding. Here you compose your SQL command with placeholders for the data and substitute them at run time.
If your ID is generated from a mysql auto insert id, then you can read the value from $conn->lastinsertid
$stmt=$conn->prepare("INSERT INTO user (firstname, lastname, email)
VALUES (:fnm,:lnm,:eml)");
$stmt->execute(array(
':fnm' => $_POST["first_name"],
':lnm' => $_POST["last_name"],
':eml' => $_POST["email"]));
$id=$conn->lastinsertid();
Your next problem is how to communicate this securely to the page where the user submits their guestbook comment (in your example code you try to do both operations in the same page).
Sending it in a round trip to the browser, as a cookie or as form variable means that it could be tampered with. There are esoteric stateless solutions where you can do this but with the data encrypted or cryptographically signed, however the simplest solution is to use sessions - add session_start() at the top of all your pages and any data you want available across requests can be stored in the $_SESSION superglobal.
(there are security issues relating to sessions as well)
When you receive the POST containing the guestbook data, then you should use an UPDATE user SET guestbook=:gstbk WHERE id=:id_from_session (or you could INSERT it into a seperate table with id as a foreign key)
Lastly, when you output the message the person left in your guestbook, make sure you protect the browser from any nasties in there:
print htmlentities($guestbook);

Ok, probably I managed to get what you need. Put the following two lines in your dbconfig.php:
$conn = new PDO("mysql:host=$servername;dbname=projektone", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
and then require it wherever you need a database connection:
file one:
require('dbconfig.php');
$sql = "sql 1";
$conn->query($sql);
then in another file
require('dbconfig.php');
$sql = "sql 2";
$conn->query($sql);

Related

MySQL Insert Into PHP Not Working

I am currently looking to run a basic insert query using PHP to submit HTML form data to MySQL database.
Unfortunately however the insert process isnt running.
In my Insert syntax I have tried including $_POST[fieldname], ive tried including variables as below, and ive even played around with different apostrphes but nothing seems to be working.
as a side dish, im also getting truck load of wamp deprication errors which is overwhelming, ive disabled in php.ini and php for apache.ini file and still coming up.
If anyone can advise what is wrong with my insert and anything else id be much thankful.
Ill keep this intro straightfoward.
Person logs in, if they try to get in without login they go back to login page to login.
I connect to database using external config file to save me updating in 50 places when hosting elsewhere.
Config file is working fine so not shown below.
database is called mydb.
Im storing the text field items into variables, then using the variables in the insert query.
unitID is an auto increment field so I leave that blank when running the insert.
Unfortunately nothing is going in to the mysql database.
Thanks in advance.
PS the text fieldnames are all correctly matched up
<?php
//Start the session
session_start();
//check the user is logged in
if (!(isset($_SESSION['Username']) )) {
header ("Location: LoginPage.php?i=1");
exit();
}
//Connect to the database
include 'config.php';
$UserName = $_SESSION['Username'];
$UserIdentification = $_SESSION['UserID'];
if(isset($_GET['i'])){
if($_GET['i'] == '1'){
$tblName="sightings";
//Form Values into store
$loco =$_POST['txtloco'];
$where =$_POST['txtwhere'];
$when =$_POST['txtdate'];
$time =$_POST['txttime'];
$origin =$_POST['txtorigin'];
$dest =$_POST['txtdest'];
$headcode =$_POST['txtheadcode'];
$sql= "INSERT INTO sightings (unitID, Class, Sighted, Date, Time, Origin, Destination, Headcode, UserID) VALUES ('','$loco', '$where', '$when', '$time', '$origin', '$dest', '$headcode', '$UserIdentification')";
mysql_select_db('mydb');
$result=mysql_query($sql, $db);
if($result){
$allocationsuccess = "Save Successful";
header ('Refresh: 2; url= create.php');
}
else {
$allocationsuccess = "The submission failed :(";
}
}
}
?>
"unitID is an auto increment field so I leave that blank when running
the insert"
That's not how it works. You have to omit it completely from the INSERT statement. The code thinks you're trying to set that field to a blank string, which is not allowed.
$sql= "INSERT INTO sightings (Class, Sighted, Date, Time, Origin, Destination, Headcode, UserID) VALUES ('$loco', '$where', '$when', '$time', '$origin', '$dest', '$headcode', '$UserIdentification')";
should fix that particular issue. MySQL will generate a value automatically for the field and insert it for you when it creates the row.
If your code had been logging the message produced by mysql_error() whenever mysql_query() returns false then you'd have seen an error being generated by your query, which might have given you a clue as to what was happening.
P.S. As mentioned in the comments, you need to re-write your code with a newer mysql code library and better techniques including parameterisation, to avoid the various vulnerabilities you're currently exposed to.

Security vulnerabilities in code to insert and return last inserted row number

I have the following code which is supposed to insert a row into a DB table "clicks" (consisting 1 Primary AI column "id" and another column "user" which contains the user's sessions id) upon clicking the Like button. For each user assuming they have a session id set from a login I would like to return to them their most recently inserted id from the table. So the first time the button is clicked it will return 1 etc.
I would like this to be accessible to multiple users through a login system. I was wondering if there are any major security vulnerabilities with my code e.g can the results be forged etc?
index.php:
<?php
include 'init.php';
include 'connect.php';
?>
<!doctype html>
<html>
<body>
<?php
$userid = $_SESSION['user_id'];
echo '<a class="like" href="#" onclick="like_add(', $userid,
');">Like</a>';
?>
<script type ="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type ="text/javascript" src="like.js"></script>
</body>
</html>
connect.php:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "DB";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
init.php:
<?php
session_start();
$_SESSION['user_id']='1';
$userid = $_SESSION['user_id'];
include 'connect.php';
include 'like.php';
?>
like.js:
function like_add(userid) {
$.post('like_add.php', {userid:userid}, function(data) {
if (data == 'success'){
add_like($userid);
} else{
alert(data);
}
});
}
like.php:
<?php
function add_like($userid){
include 'connect.php';
$stmt = $conn->prepare("INSERT INTO clicks (user) VALUES (?)");
$stmt->bind_param("s", $userid);
$stmt->execute();
$stmt = $conn->prepare("SELECT max(id) FROM clicks WHERE user=?");
$stmt->bind_param("s", $userid);
$stmt->execute();
$stmt->bind_result($click);
$stmt->fetch();
echo $click;
$stmt->close();
}
?>
like_add.php:
<?php
include 'init.php';
if (isset($userid)) {
$userid = $userid;
add_like($userid);
}
?>
Your query might give incorrect results if the same user sends multiple requests almost at the same time, case when your query will not return the currently inserted id. You can use the last_insert_id() mysql function which gives you the last inserted auto-increment value, regardless if meanwhile other requests updated the table.
Also, you don't need to pass the user_id parameter with the ajax request, as you anyway can obtain it from the session. Passing the user_id can be considered a security hole, as anyone can modify the onclick handler and trigger clicks for other users. I'd recommend avoiding as much as possible sending user ids in plain text as response.
To add more security: in your connection script. Change the $servername, $username etc to constants. These don’t need to change, and you don’t want them to be changed.
Do you have any type of checks for your sessions? Sessions are more secure than cookies but they can be hijacked in transit when a user logs in. To add some security to your session, use the session_regenerate_id() function when the user logs in, this will generate a new session id therefore if the users id has been hijacked, it is of no use as it will have changed. There are other checks that can be carried out on sessions to secure them but this is a good quick way of adding an extra level.
#nomistic makes some good suggestions also especially regarding encryption of passwords and other sensitive information. Using the crypt() function or PHP’s password hashing API - http://php.net/manual/en/book.password.php. Is also a good way.
This looks pretty good on the php side. You are using session ids for user verification, and have prepared your SQL inserts. (One question, why are you setting $_SESSION['user_id']='1'? Do you plan on only having one user? That doesn't seem necessary to me)
However, you might want to tighten up your database-side security. It's probably a good idea to set up a different user for public database access, and limit the actions on the database side. For instance, if all they are going to do is select or insert, that user should only have access to do so. I wouldn't use your root account for that. Though it's probably not a huge risk (you are doing pretty well against SQL injection, at least the first two times) just to add another layer is always a good idea.
When dealing with security, it's helpful to think of a "use-case" scenario. What sort of data are you storing? Is it something that somebody really would want? (e.g. is it financial?) It's always a good idea to look at the human element. Would someone want to spend more than a day trying to hack your data (is it worth it for them?).
Also, though it's not evident here, you probably want to make sure you have a good form of encrypting passwords.
Another thought: even if it is minor risk, it's not a bad idea to run daily backups, so you can recover your data in a worst-case scenario.
Edit:
Since it was asked, here's how to setup security at the database side:
First create a new user (following this pattern):
CREATE USER 'newuser'#'localhost' IDENTIFIED BY 'password';
Granting permissions work like this:
GRANT [type of permission] ON [database name].[table name] TO ‘[username]’#'localhost’;
Types of privileges include ALL PRIVILEGES, CREATE,DROP, DELETE, INSERT, SELECT, UPDATE, GRANT OPTION.
If you want to read up on this more, here's the documentation: https://dev.mysql.com/doc/refman/5.1/en/adding-users.html

Update database php

mysql_query("UPDATE users SET `test` = '$unicornID' where id='$_SESSION[user_id]' ")
or die(mysql_error());
Now, when user clicks 'add to favorite'-button this line of code updates my database but also deletes all the old data from column test. What command should so that the old data is not deleted?
I think what you may be looking for is an "INSERT" sql query.
It would be something along the lines of;
"INSERT * INTO users WHERE test='$unicornID' and id='$_SESION['user_id']'";
Let me know how it goes. Cheers.
Another tip.
Use PDO with prepared statements:
$pdo = new PDO(sprintf('mysql:host=%s;dbname=%s', HOST, DATABASE), USER, PASSWORD);
And to insert something:
$params = array(':unicornID' => $unicornID, ':id' => $_SESSION['user_id']);
$stmt = $pdo->prepare("INSERT * INTO users WHERE test=:unicornID and id=:id");
$stmt->execute($params);
The old mysql(_query) commands are old and very vulnerable, PDO isn't as vulnerable.
The advantage of prepared statements are mainly that you can't inject via your variables some sql code.
Hope you understood my and my code
"Update" means that the old data row is changed; if you want to keep it, you have to insert a new one. In this case I think that you should copy the row (which may be done using "insert... select...") and then update the newly inserted line.

What is the best way to protect Mysql Delete statements?

I thought you guys would know the best way to do this:
When I delete an order ($prodId) from the ORDERS table, this script then goes and deletes all the items-ordered lines from the ORDERED_ITEMS table, which houses all the items ordered from every order in the system.
Is there a best practice to ensure that what I want deleted is deleted and only that? I'm worried about something going wrong/injected/mistyped with/into the script and accidentally deleting all the ordered item lines for all orders by mistake.
This is how far I got.
$delete_prod_items = mysqli_real_escape_string($con,$_REQUEST['prodId']);
if (is_numeric($delete_prod_items)){
$sql3 = "DELETE from proteus.ordered_items where order_id = $orderId";
mysqli_query($con,$sql3) or die('DELETE Order $orderId from the Ordered Items table failed: ' . mysqli_error($con).'<br>');
}
This script is POSTed into by my form.
$orderID is the order number that the script uses to identify which ITEM rows should be deleted
$delete_prod_item is the escaped $prodID value. I was trying to be super cautious. perhaps I don't need this.
Am I missing anything?
Don't know why anyone is mentioning it, but the best way to really protect any statement is using PreparedStatements:
$delete_prod_items = mysqli_real_escape_string($con,$_REQUEST['prodId']);
$mysqli = new mysqli("localhost", "localuser", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
if (!($stmt = $mysqli->prepare("DELETE FROM `proteus`.`ordered_items` WHERE `order_id` = ?"))) { //whatever query you want
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
$stmt->bind_param("s", $delete_prod_items);
$stmt->execute();
$stmt->close();
Also take after what #zerkms mentioned and use POST requests for your information.
First things first you need to take care of the sql injections. The link will give you an idea.
Secondly you could use javascript to get a pop-up which asks the user a confirmation before deletion.
Next, to avoid the unintentional deletion of more than one row is to include LIMIT 1 to your query.
N.B. You could also limit priveleges by creating a different user (username) to access the mysql database use it in your mysql_connect('host', 'username', 'password', 'database') function . If you are displaying something really important you may consider not giving deletion rights.
Escaping data is good for preventing SQL Injection
It's better to limit the request with $_POST instead of $_REQUEST
If this page is for admin only, then it's fine since only you have access, however, if users have access to it, therefore it's better to apply some condition to the request before proceeding to the deletion (example, verify that they are deleting something related to their accounts only)
As a first order of business, do the following...
Limit the request method to POST or even better, DELETE if you can get PHP to handle it.
Use prepared statements with bound parameters to avoid SQL injection vulnerabilities.
The main issue you will face is unauthorised requests. The best solution to this is to use a CSRF token.

Connecting to a database using php script

I have created a form in HTML and the action is set to a php script. I'm pretty new to php and was wondering if someone could help me out with it? I need to write a script to add the info from the form to a database. I need to create the database and the table as well. I did a lot of reading on the net and I'm still unable to do it. This is the script I have. Please tell me what mistakes I have made. Thank you for all the help.
<?php
$con=mysql_connect("example.com","peter","abc123","my_db");
$sql="CREATE DATABASE user";
if (mysql_query($con,$sql)) {
echo "Database user created successfully";
}
$sql="CREATE TABLE Persons(PID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(PID),firstName CHAR(30),lastName CHAR(30),age INT, dateofbirth DATE, email CHAR(30)";
if (mysql_query($con,$sql)) {
echo "connected to database";
}
$sql="INSERT INTO Persons (firstName, lastName, age, dateofbirth, email) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]','$_POST[dateofbirth]','$_POST[email]')";
if (mysql_query($con,$sql)) {
echo "added to database";
}
mysql_close($con);
?>
I tried all the suggested answers and still not able to do it. Can someone please provide the code to do that? I need to obtain data from a form and insert it into a database using php!
Hi Try This Code,
$con=mysql_connect("example.com","peter","abc123");
$sql="CREATE DATABASE user";
if (mysql_query($sql))
{
echo "Database user created successfully";
}
1.- Don't use mysql_ functions because are deprecated, use mysqli_ functions or PDO instead.
2.- You have several error i guess, first of all you select a database my_db on the connection script, but you are created another database in the next line... it's very strange this behaviour. If this script executes every time then you should change your code (you can't create a database and a table every time.
In the insert string you have an error with the post code, try this:
$sql="INSERT INTO Persons (firstName, lastName, age, dateofbirth, email) VALUES ('{$_POST['firstname']}','{$_POST['lastname']}','{$_POST['age']}','{$_POST['dateofbirth']}','{$_POST['email']}')";
Your CREATE TABLE query will fail because of syntax error. You have to check queries results especially when next query depends on previous (and you're doing operations like creating databases/tables).
Next thing to change is mysql_*. This functions are deprecated and instead you should use PDO or mysqli_* (they are not hard to learn, just try).
And one more important change have to be done in your script. You're getting user input and adding it to query. Don't do that! You have to always assume that user is trying to hack you, so all inputed data have to be checked and filtered. Also it's good to use prepared statements with such data.
if (mysql_query($con,$sql)){
echo "Database user created successfully";
} else {
echo 'Error creating database - ' . mysql_error();
}
Same thing for all your sql statements to see where you went wrong
Change your code (mysql_query($sql)) instead of (mysql_query($con,$sql))

Categories