Prevent users to edit eachother entries - php

I have a PHP script that allow users to register entries to a database. Entries are autoincremented. What I found out, is that user #A can get an entry from user #B by changing url from edit.php?id=2 to id=1.
Of course I want to prevent that. So my idea: if the user ID field in the mysql entry matches $_SESSION['user_id'] in my php script, editing is allowed.
A user should only be able to edit entries they have posted themselves.
What would be the best and most efficient way to achieve this?
<?php $bruker = $_SESSION['user_id']; ?>
<?php }
/*
EDIT RECORD
*/
// if the 'id' variable is set in the URL, we know that we need to edit a record
if (isset($_GET['id']))
{
// if the form's submit button is clicked, we need to process the form
if (isset($_POST['submit']))
{
// make sure the 'id' in the URL is valid
if (is_numeric($_POST['id']))
{
// get variables from the URL/form
$id = $_POST['id'];
$elv = htmlentities($_POST['elv'], ENT_QUOTES);
$vald = htmlentities($_POST['vald'], ENT_QUOTES);
$art = htmlentities($_POST['art'], ENT_QUOTES);
$dato = htmlentities($_POST['dato'], ENT_QUOTES);
$vekt = (int)$_POST['vekt'];
$lengde = (int)$_POST['lengde'];
$flue = htmlentities($_POST['flue'], ENT_QUOTES);
$gjenutsatt = (int)$_POST['gjenutsatt'];
$kjonn = (int)$_POST['kjonn'];
$bilde = htmlentities($_POST['bilde'], ENT_QUOTES);
$user = $_SESSION['user_id'];
// check that required fields are not empty
if ($elv == '' || $vald == '' || $art == '' || $dato == '' || $vekt == '' || $kjonn == '')
{
// if they are empty, show an error message and display the form
$error = 'Du må fylle ut de påkrevde feltene!';
renderForm($elv, $vald, $art, $dato, $vekt, $lengde, $flue, $gjenutsatt, $kjonn, $bilde, $user, $error, $id);
}
else
{
// if everything is fine, update the record in the database
if ($stmt = $mysqli->prepare("UPDATE fisk SET elv = ?, vald = ?, art = ?, dato = ?, vekt = ?, lengde = ?, flue = ?, gjenutsatt = ?, kjonn= ?, bilde = ?, user = ?
WHERE id=?"))
{
$stmt->bind_param("ssssiisiisii", $elv, $vald, $art, $dato, $vekt, $lengde, $flue, $gjenutsatt, $kjonn, $bilde, $user, $id);
$stmt->execute();
$stmt->close();
}
// show an error message if the query has an error
else
{
echo "ERROR: could not prepare SQL statement.";
}
// redirect the user once the form is updated
header("Location: /");
}
}
// if the 'id' variable is not valid, show an error message
else
{
echo "Error!";
}
}
// if the form hasn't been submitted yet, get the info from the database and show the form
else

Assuming your users have unique ID's you can simply add additional WHERE clause to your SQL:
if ($stmt = $mysqli->prepare("UPDATE fisk SET elv = ?, vald = ?, art =
?, dato = ?, vekt = ?, lengde = ?, flue = ?, gjenutsatt = ?, kjonn= ?,
bilde = ?, user = ?
WHERE id=? AND created_user = ?"))
Obviously replace created_user with the column you use to store the users ID who created the entry.
That way it will only ever update a row created by the user trying to edit it.
More securely, you could prevent them from ever seeing the page by first querying the created user id of the row in question then checking it against your user id $_SESSION as you suggest - then killing the script or redirecting them before it ever gets to the query.

Related

PHP sql SELECT from database is working, but sql INSERT INTO database is not working even though success message is shown [duplicate]

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 3 years ago.
I'm trying something new and at the same time practicing PHP. I have checked all the previous posts on StackOverflow and couldn't find the solution. I'm trying to insert some data into the database using PHP and PhpMyAdmin. Now the problem I'm facing is that the data from the database can be displayed (SELECT FROM) if I enter the data manually. When I try to insert data into the database dynamically using PHP example:
$sql = "INSERT INTO apps (appName, appDescription, appLinkFacebook, appLinkInstagram, appLinkPlaystore, appLinkWeb,appGoogleGamesIcon, appFullImageNameBackground, appFullImageNameIcon) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
I get no errors and I also get a success message that is supposed to show after the INSERT command was finished. The images I'm trying to insert are also successfully created inside designated folders and their names are also displayed in the right way. I already checked all the input fields names from the form, all the links and spelling a just can't seem to find the problem. I also tried using INSERT command while using the database on localhost and on a remote server and still nothing. If anyone has an idea on what to do please tell. Thanks
Here is the full source code of my upload.php file.
<?php
if (isset($_POST['btnUpload'])) {
$newFileNameCardBackground = $_POST['imgNameCardBackground'];
if (empty($newFileNameCardBackground)) {
$newFileNameCardBackground = "card_background";
} else {
$newFileNameCardBackground = strtolower(str_replace(" ", "-", $newFileNameCardBackground));
}
$newFileNameCardIcon = $_POST['imgNameCardIcon'];
if (empty($newFileNameCardIcon)) {
$newFileNameCardIcon = "card_icon";
} else {
$newFileNameCardIcon = strtolower(str_replace(" ", "-", $newFileNameCardIcon));
}
$appName = $_POST['appName'];
$appDescription = $_POST['appDescription'];
$appLinkFacebook = $_POST['appLinkFacebook'];
$appLinkInstagram = $_POST['appLinkInstagram'];
$appLinkPlaystore = $_POST['appLinkPlaystore'];
$appLinkWeb = $_POST['appLinkWeb'];
$appGoogleGamesIcon = $_POST['appGoogleGamesIcon'];
$fileCardBackground = $_FILES['fileCardBackground'];
$fileNameCardBackground = $fileCardBackground["name"];
$fileTypeCardBackground = $fileCardBackground["type"];
$fileTempNameCardBackground = $fileCardBackground["tmp_name"];
$fileErrorCardBackground = $fileCardBackground["error"];
$fileSizeCardBackground = $fileCardBackground["size"];
$fileCardBackgroundExtension = explode(".", $fileNameCardBackground);
$fileCardBackgroundActualExtension = strtolower(end($fileCardBackgroundExtension));
$fileCardIcon = $_FILES['fileCardIcon'];
$fileNameCardIcon = $fileCardIcon["name"];
$fileTypeCardIcon = $fileCardIcon["type"];
$fileTempNameCardIcon = $fileCardIcon["tmp_name"];
$fileErrorCardIcon = $fileCardIcon["error"];
$fileSizeCardIcon = $fileCardIcon["size"];
$fileCardIconExtension = explode(".", $fileNameCardIcon);
$fileCardIconActualExtension = strtolower(end($fileCardIconExtension));
$allowed = array("jpeg", "jpg", "png", "JPEG", "JPG", "PNG");
if (in_array($fileCardBackgroundActualExtension, $allowed) && in_array($fileCardIconActualExtension, $allowed)) {
if ($fileErrorCardBackground === 0 && $fileErrorCardIcon === 0) {
$imageFullNameCardBackground = $newFileNameCardBackground . "." . uniqid("", true) . "." . $fileCardBackgroundActualExtension;
$fileDestinationCardBackground = "../../img/card_background/" . $imageFullNameCardBackground;
$imageFullNameCardIcon = $newFileNameCardIcon . "." . uniqid("", true) . "." . $fileCardIconActualExtension;
$fileDestinationCardIcon = "../../img/card_logo/" . $imageFullNameCardIcon;
include 'connection.php';
if (empty($appName) && empty($appDescription) && empty($appGoogleGamesIcon)) {
header("Location: ../../admin/admin-main.php?upload=SelectedFields-MUST-NOT-BeEmpty");
exit();
} else {
$sql = "SELECT * FROM apps;";
$statement = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($statement, $sql)) {
echo "SQL statment failed";
} else {
mysqli_stmt_execute($statement);
$result = mysqli_stmt_get_result($statement);
$rowCount = mysqli_num_rows($result);
$sql = "INSERT INTO apps (appName, appDescription, appLinkFacebook, appLinkInstagram, appLinkPlaystore, appLinkWeb,
appGoogleGamesIcon, appFullImageNameBackground, appFullImageNameIcon) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
if (!mysqli_stmt_prepare($statement, $sql)) {
echo "SQL statment failed";
} else {
mysqli_stmt_bind_param(
$statement,
"sssssssss",
$appName,
$appDescription,
$appLinkFacebook,
$appLinkInstagram,
$appLinkPlaystore,
$appLinkWeb,
$appGoogleGamesIcon,
$appFullImageNameBackground,
$appFullImageNameIcon
);
mysqli_stmt_execute($statement);
move_uploaded_file($fileTempNameCardBackground, $fileDestinationCardBackground);
move_uploaded_file($fileTempNameCardIcon, $fileDestinationCardIcon);
header("Location: ../../admin/admin-main.php?upload=success");
}
}
}
} else {
echo "You have an error";
exit();
}
} else {
echo "Yopu need to upload a proper file type";
exit();
}
}
So to sum it up sql SELECT is working when I enter the data manually, images are where they are supposed to be under the right name and there are no errors.
Thanks :D
Found the problem by using this command above my sql statement. Everything works now.
Thanks for your help.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

How to fix that stmt->execute() always returns false?

I am working on a php project with a database. I want users to be able to comment articles (I have already a working system for article creation) but I cannot insert the comments in the database. Here is the code:
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$content = filter_input(INPUT_POST, 'new_entry', FILTER_SANITIZE_STRING);
$author = $_SESSION["username"];
$article_id = $_GET['article'];
$rating = 0;
if ($insert_stmt = $mysqli->prepare("INSERT INTO `entries` (`article_id`, `rating`, `content`, `author`) VALUES (?, ?, ?, ?)")) {
$insert_stmt->bind_param('iiss', $article_id, $rating, $content, $author);
// Führe die vorbereitete Anfrage aus.
if ($insert_stmt->execute()) {
header('Location: success.php');
} else {
header('Location: failure.php');
}
}
This is always directing me to 'failure.php' - what is the problem here?
I thank you in advance!
Because You have,
$article_id = $_GET['article'];
in your code, While you are POSTing the form data,
So your $article is null or "".
That's why it is redirecting to failure.php.
Instead use,
$article_id = $_POST['article'];
I am sorry for the incovenience I caused, but I found a solution myself.
Instead of getting the article_id from GET directly, I created a hidden input field with its value:
<input type="hidden" name="article" value="<?php echo $_GET['article'] ?>">
Now I can access this value with POST, what works perfectly:
$article_id = $_POST['article'];
I hope that I could help anyone with this!

mysql php script only works first time

I have a script to add companies and categories to a database, however it only works first time. When I try to add a second company, it fails on the final error check after passing all other error checks. The category is added successfully to the categories table but the company and its details do not get added to the companies table.
Is this likely to be a code error or an error in my database construction?
Here is the final error check and mysql query:
if (empty($errors)) { // If everything's OK.
// Add the company to the database:
$q = 'INSERT INTO companies (category_id, company_name, phone, email, website, address_1, address_2, address_3, postcode, description, image_name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$stmt = mysqli_prepare($dbc, $q);
mysqli_stmt_bind_param($stmt, 'issssssssss', $catid, $cn, $p, $e, $w, $a1, $a2, $a3, $pc, $d, $i);
mysqli_stmt_execute($stmt);
// Check the results...
if (mysqli_stmt_affected_rows($stmt) == 1) {
// Print a message:
echo '<p>The company has been added.</p>';
// Rename the image:
$id = mysqli_stmt_insert_id($stmt); // Get the company ID.
rename ($temp, "../../../uploads/$id");
// Clear $_POST:
$_POST = array();
} else { // Error!
echo '<p style="font-weight: bold; color: #C00">Your submission could not be processed due to a system error.</p>';
}
mysqli_stmt_close($stmt);
} // End of $errors IF.
Here is the entire code:
<?php
require_once ('../../../mysqli_connect.php');
if (isset($_POST['submitted'])) { // Handle the form.
// Validate the incoming data...
$errors = array();
// Check for a company name:
if (!empty($_POST['company_name'])) {
$cn = trim($_POST['company_name']);
} else {
$errors[] = 'Please enter the company\'s name!';
}
// Check for an image:
if (is_uploaded_file ($_FILES['image']['tmp_name'])) {
// Create a temporary file name:
$temp = '../../../uploads/' . md5($_FILES['image']['name']);
// Move the file over:
if (move_uploaded_file($_FILES['image']['tmp_name'], $temp)) {
echo '<p>The file has been uploaded!</p>';
// Set the $i variable to the image's name:
$i = $_FILES['image']['name'];
} else { // Couldn't move the file over.
$errors[] = 'The file could not be moved.';
$temp = $_FILES['image']['tmp_name'];
}
} else { // No uploaded file.
$errors[] = 'No file was uploaded.';
$temp = NULL;
}
// Validate the category...
if (isset($_POST['category']) && ($_POST['category'] == 'new') ) {
// If it's a new category, add the category to the database...
// Check for a category name...
if (!empty($_POST['category_name'])) {
$catn = trim($_POST['category_name']);
// Add the category to the database:
$q = 'INSERT INTO categories (category_name) VALUES (?)';
$stmt = mysqli_prepare($dbc, $q);
mysqli_stmt_bind_param($stmt, 's', $catn);
mysqli_stmt_execute($stmt);
// Check the results....
if (mysqli_stmt_affected_rows($stmt) == 1) {
echo '<p>The category has been added.</p>';
$catid = mysqli_stmt_insert_id($stmt); // Get the category ID.
} else { // Error!
$errors[] = 'The new category could not be added to the database!';
}
// Close this prepared statement:
mysqli_stmt_close($stmt);
} else { // No category name value.
$errors[] = 'Please enter the category\'s name!';
}
} elseif ( isset($_POST['category']) && ($_POST['category'] == 'existing') && ($_POST['existing'] > 0) ) { // Existing category.
$catid = (int) $_POST['existing'];
} else { // No category selected.
$errors[] = 'Please enter or select the category\'s name!';
}
if (empty($errors)) { // If everything's OK.
// Add the company to the database:
$q = 'INSERT INTO companies (category_id, company_name, image_name) VALUES (?, ?, ?)';
$stmt = mysqli_prepare($dbc, $q);
mysqli_stmt_bind_param($stmt, 'iss', $catid, $cn, $i);
mysqli_stmt_execute($stmt);
// Check the results...
if (mysqli_stmt_affected_rows($stmt) == 1) {
// Print a message:
echo '<p>The company has been added.</p>';
// Rename the image:
$id = mysqli_stmt_insert_id($stmt); // Get the company ID.
rename ($temp, "../../../uploads/$id");
// Clear $_POST:
$_POST = array();
} else { // Error!
echo '<p style="font-weight: bold; color: #C00">Your submission could not be processed due to a system error.</p>';
}
mysqli_stmt_close($stmt);
} // End of $errors IF.
// Delete the uploaded file if it still exists:
if ( isset($temp) && file_exists ($temp) && is_file($temp) ) {
unlink ($temp);
}
} // End of the submission IF.
// Check for any errors and print them:
if ( !empty($errors) && is_array($errors) ) {
echo '<h1>Error!</h1>
<p style="font-weight: bold; color: #C00">The following error(s) occurred:<br />';
foreach ($errors as $msg) {
echo " - $msg<br />\n";
}
echo 'Please reselect the company image and try again.</p>';
}
// Display the form...
?>
I needed to specify the primary key as auto-increment, in this case it is the company_id field.
A simple way to add detailed error checking is to insert
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
before the mysqli_connection is made.

INSERT INTO not inserting for me

I can't see anything wrong with this, but it just wont work.
Quick rundown: Form filled in on previous page, $_POST['']'s added to $_SESSION['']'s, $vars set from the $_SESSION['']'s, $vars used to mysqli_query.
Im sure the problem is staring me in the face, but I just cant see it.
Heres the code: (UPDATED)
if(isset($_POST['list_make']) && $_POST['list_make'] != '') { $list_make = $_POST['list_make']; $_SESSION['list_make'] = $list_make; }
if(isset($_SESSION['list_make']) && $_SESSION['list_make'] != '') { $list_make = $_SESSION['list_make']; } else { $list_make = ''; }
$add_car_query = "INSERT INTO car_details
(car_user_id, car_user_number, car_date_added, car_make, car_model, car_date_registered, car_odometer,
car_engine_size, car_color, car_body_type, car_owners, car_nct_date, car_rax_date)
VALUES
('$user_id_new', '$new_user_number', '$today', '$list_make', '$list_model', '$list_year', '$list_kilometers',
'$list_engine_size', '$list_color', '$list_body_type', '$list_previous_owners', '$list_nct', '$list_tax')
";
if(mysqli_query($con, $add_car_query)) { $added = 'added'; } else { $added = 'Not happening'; }
Try checking if there is a MySQLi error in the else (which will be triggered if the query fails):
$add_car_query = "INSERT INTO car_details
(car_user_id, car_user_number, car_date_added, car_make, car_model, car_date_registered, car_odometer,
car_engine_size, car_color, car_body_type, car_owners, car_nct_date, car_rax_date)
VALUES
('$user_id_new', '$new_user_number', '$today', '$list_make', '$list_model', '$list_year', '$list_kilometers',
'$list_engine_size', '$list_color', '$list_body_type', '$list_previous_owners', '$list_nct', '$list_tax')
";
if(mysqli_query($con, $add_car_query)) {
$added = 'added';
}
else {
// check for the error here
if(mysqli_error()) {
echo mysqli_error();
}
$added = 'Not happening';
}
Prepared Statements
As someone in the comments said, you should use prepared statements for better security. This way you don't have to worry about escaping input (it looks like you aren't escaping the values right now which is very dangerous).
It can get a bit confusing with the question mark placeholders though (MySQLi doesn't support named parameters unfortunately). Prepared statements are nicer with OOP MySQLi, but you're using procedural so here's how you do a prepared statement for the query in your question:
$add_car_query = "INSERT INTO car_details
(car_user_id,
car_user_number,
car_date_added,
car_make,
car_model,
car_date_registered,
car_odometer,
car_engine_size,
car_color,
car_body_type,
car_owners,
car_nct_date,
car_rax_date)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = mysqli_stmt_prepare($con, $add_car_query);
// if any of the values are an int, change the
// corresponding 's' (which means string) to 'i' (integer).
// more info: http://us.php.net/manual/en/mysqli-stmt.bind-param.php
mysqli_stmt_bind_param($stmt, 'sssssssssssss',
$user_id_new,
$new_user_number,
$today,
$list_make,
$list_model,
$list_year,
$list_kilometers,
$list_engine_size,
$list_color,
$list_body_type,
$list_previous_owners,
$list_nct,
$list_tax);
$stmt_exe = mysqli_stmt_execute($stmt);
if($stmt_exe) {
$added = 'added';
}
else {
if(mysqli_error()) {
echo mysqli_error();
}
$added = 'Not happening';
}

Get data won't insert

I've been using $_GET data to send data across pages and it has been working fine.
What i have on one page is news. Each news article has its own specific ID (and this page works perfectly fine). I can click on an add me button next to each event to add myself as a volunteer for organising the BBQ for that event. However now i'm trying to click on an add button which can add other users to the BBQ.
I've checked to see if the $_GET data is returning anything on page load and it does, however the values are lost when i click submit. So, when i check to see if it returns anything inside the isset($_POST['userselect']), the values are lost:
Here is my code:
$rosterID = $_GET["rosterid"];
$eventID = $_GET["eventid"];
//if i check to see if they gets work here, they do.
if (hasRole2($connection, "Admin") || hasRole2($connection, "Moderator") || hasRole2($connection, "BBQ Moderator")){
$usernames[] = array();
if ($stmt = $connection->prepare("SELECT id, uid from people")){
$stmt->execute();
$stmt->bind_result($id, $username);
$stmt->store_result();
$form = new jqmForm();
$form->method('post');
$sel = $form->add(new jqmSelect('userselect','userselect','<p align="center">Select User:</p>'), true);
while ($stmt->fetch()){
$usernames[] = array('uid' => $username, 'id' => $id);
$optName = $username;
$optValue = $id;
$sel->add(new jqmOption($optName, $optValue, false));
$sel->attribute('data-native-menu', 'false');
}
$stmt->close();
$form->add(new jqmInput('submit', 'submit', 'submit', 'submit', '', 'b', true));
}
if (isset($_POST["userselect"])){
//if i check to see if the gets work here, they don't.
$personID = $_POST["userselect"];
if (rostered($connection, $personID, $rosterID, $eventID)){
$personID = $_POST["userselect"];
$p->addContent("<p align=center><font color = red>You have already rostered for this event</font></p>");
$login = $p->addContent("<font color=brown size=4><a href = news.php rel=external> Go back </a></font>");
$login->attribute('align', 'center');
}
else{
$search = "INSERT INTO RosterPeopleEvent (roster_id, person_id, news_id) VALUES (?, ?, ?)";
if (!$roster = $connection->prepare($search)){
$p->addContent("Inserting into RosterPeopleEvent Prepare failed: (" . $connection->errno . ") " . $connection->error);
}
else{
$roster->bind_param("iii", $_GET["rosterid"], $personID, $_GET["eventid"]);
$roster->execute();
}
}
}
}
Just added:
$form->action("url.php?rosterid=$rosterID&eventid=$eventID");
This worked.

Categories