My poll has a 'back button' loophole - php

Have had a couple questions answered very nicely here and I've got some more trouble someone can probably help with:
I have SQL database that holds a poll question answer and a user IP address. Here is my (now working!) PHP code:
// check to see if user has already voted
$current_user = $_SERVER['REMOTE_ADDR'];
$select_query = "SELECT * FROM w_poll_counter WHERE user_IP = '" . $current_user ."';";
$result = mysql_query($select_query);
if($result)
{
$row = mysql_fetch_array($result);
$user_from_db = $row['user_IP'];
if($current_user === $user_from_db)
{
//user already voted - show results page
header("Location: scripts/show_results.php");
exit();
}
}
The code works great, except there's one problem... After a user votes and sees the results page, they can click the browser's 'back' button and then simply vote again, since the code to check their IP address doesn't run in that instance.
What do I need to do to fix this issue?
Thanks!

Check if the user has already voted before executing your update statement.
Also you should take better care, your script is very vulnerable to sql injections. https://stackoverflow.com/a/60496/3595565
I can show you this example of an implementation via pdo:
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8;', 'dbUser', 'dbPassword');
$stmtCheck = $pdo->prepare("SELECT * FROM w_poll_counter WHERE user_IP = ?");
$stmtCheck->execute(array($_SERVER['REMOTE_ADDR']));
$result = $stmtCheck->fetchAll(PDO::FETCH_ASSOC);
if(count($result) === 0){
//update
}

Related

Admin check on certain statements - cannot pass true/false value

Firstly, please forgive me if i don't give enough info in my question, i'm new to the developer scene after just landing myself an amazing opportunity as a junior software developer role a few weeks ago.
I have a project i'm working on which is a basic CRUD management system.
I have a login process and user accounts all setup but i would like certain things to require "Admin" privileges like deleting items from my inventory.
So currently everything works as is (just no admin checking)
i have made this function in my config.php (which is included on every page through the header)
function checkAdmin($conn)
{
$id = $_SESSION['member_id'];
$sql = "SELECT admin FROM members WHERE id = $id";
$query = mysqli_query($conn, $sql);
$rs = mysqli_fetch_array($query);
$admin = $rs['admin'];
if($admin == 1){
return true;
}else{
return false;
}
}
So my question is, how do i then pass that value "true/false" into my query.
Im using jQuery/Ajax to do my queries but i understand this would be handed on my "ajax.php" page where all my queries are.
my current code is:
if(isset($_GET['deleteID']))
{
if('checkAdmin' == true){
$id = $_GET['deleteID'];
$sql = "DELETE FROM members WHERE id=$id";
mysqli_query($conn, $sql);
recordLog($conn, "Members", "Removed user #$id");
$data = [
'success' => true
];
}else{
$data = [
'error' => 'Admin Privileges Required'
];
}
echo json_encode($data);
}
the actual code in itself works, without the If(checkAdmin == statement but i dont think i'm on the right lines with it.
Thanks in advance for any help :) please let me know if any more info is needed
Call the function in the if statement:
if(checkAdmin($conn) == true){
Alternately you could do:
$checkAdmin = checkAdmin($conn);
if($checkAdmin == true){
Be advised that you are at serious risk of SQL Injection. Implement this now: How can I prevent SQL injection in PHP? This is bad, bad, bad:
$id = $_GET['deleteID'];
$sql = "DELETE FROM members WHERE id=$id";

PHP login system help needed for deletion

Help with user deletion:
Hello I am creating a user creation system for a project of mine, I am still very new to PHP, my issue is getting the user from the MySQL database and then deleting it, I will show you my code below:
<?php
require_once("config/db.php");
if ($login->isUserLoggedIn() == true) {
if ($_SESSION['user_perm'] == 1) {
//Create Connection
$db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// Check connection
if ($db_connection->connect_error) {
die("Connection failed: " . $db_connection->connect_error);
}
$sql = "SELECT user_name FROM users";
$result = $db_connection->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["user_name"];
$user_name_delete = $row["user_name"];
$_SESSION['user_name_delete'] = $user_name_delete;
echo 'Delete User<br>';
}
}
}
$db_connection->close(); ?>
On the deleteuser.php page my code is, note this was just a test:
<?php
echo $_SESSION['user_name_delete'];
?>
My issue with this is grabbing the user who you selected to delete as at the moment it only outputs the last user grabbed from the database.
Any help is much appreciated.
This value:
$_SESSION['user_name_delete']
Is going to contain only the last user in your data. Because you keep overwriting it in your loop:
$_SESSION['user_name_delete'] = $user_name_delete;
The short answer is... Don't use session state for this. (Really, you shouldn't use session state for much of anything unless you absolutely have to.) The identity of the user to be deleted should be included in the request to delete the user. In this case, you can add it to the link. Something like this:
echo 'Delete User<br>';
(Or whatever you use to identify the user in the data row.)
Then in deleteuser.php you can get that value from:
$_GET['id']
Validate the inputs, validate that the user is authorized to perform the delete, and then use that value in the WHERE clause of your DELETE query.
Get the users id and insert it into a delete query.
$id = $db->real_escape_string($_GET['id']);
$sql = "delete from users where id = " . $id; and then run the query to delete the user from the database.

Problems updating MySQL, "username" in a table using PHP

I'm probably not using the best method to create a user system, but it doesn't need to be fancy. I also know that I'm not the most organized
The logins and everything are alright, but I'm having a problem updating the credentials.
For example, I'm allowing users to change their username. I have the "Change Username" (Not that name) form to submit to update-username.php.
I already have mysql_real_escape_string, in the function "cleanString" in another page. My textarea submitting already has the old text in it, so you can change and view it before hand.
$user_id = "";
if(isset($_POST['id']))
{
$user_id = $_POST['id'];
}
$query = "SELECT username,email,display_name,access,password FROM users WHERE user_id='$user_id'";
$results = mysql_query($query);
if(!$results) { //Check to see if query failed
die(mysql_error());
}
$resultsfetch=mysql_fetch_array($results);
$username = $resultsfetch['username'];
$usernamenew = $_POST['usernameinput'];
if(isset($_POST['usernameinput'])) {
$usernamenew = cleanString($_POST['usernameinput']);
}
if($usernamenew !=$username){
$submit = "UPDATE users SET username = '$usernamenew' WHERE user_id = '$user_id'";
mysql_query($submit);
if(!$submit) { //Check to see if query failed
die(mysql_error());
}
}
It's probably something stupid or simple that I missed, or something really huge. Mainly because I am absent minded.
$submit = sprintf("UPDATE users SET username = '%s' WHERE user_id = %d",mysql_real_escape_string($usernamenew),mysql_real_escape_string($user_id));
If the page is loaded, $user_id will be NULL so noting will be updated! Make sure that this page loads, by sending $_POST['id'] . if these things are correct, check this.
"Did the database user have any permission to update the table? "
I have re-arranged your code. added comments where i changed. Try this
if (isset($_POST['id'], $_POST['usernameinput'])) { // Check if both POST id and usernameinput is available
$user_id = (int)$_POST['id']; //assuming this is an integer
$query = "SELECT username,email,display_name,access,password FROM users WHERE user_id='$user_id'";
$results = mysql_query($query);
if (!$results) {//Check to see if query failed
die(mysql_error());
}
if (mysql_num_rows($result) > 0) { //verify if there is really a user with such id
$resultsfetch = mysql_fetch_array($results);
$username = $resultsfetch['username'];
$usernamenew = cleanString($_POST['usernameinput']);
if ($usernamenew != $username) {
$submit = "UPDATE users SET username = '$usernamenew' WHERE user_id = '$user_id'";
if (!mysql_query($submit)) {//Check to see if query failed
die(mysql_error());
}
}
}else{
die("no such user with userid=$user_id");
}
}
Warning: mysql_ function is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used.
So, I guess I figured it out. It's an issue with my code carrying over to the next page.
The code I had been shown only broke the page, whether it be missing an integer, or something else. I'm not 100% sure.
Thanks for all the help guys, but now I know the issue.
EDIT:
I had forgotten to echo the $user_id in my hidden field.

Session Confliction Error

Am creating a website where people can leave their opinions on releases by rating them and this gets stored into a MySQL database which is driven by PHP.
I have a feedback form for one particular release, which (lets say in this example) has the ID of 35. When I send a user another one which has the ID of 36 and the user has both windows open, the PHP processing code stores the responses from ID 35 but with ID 36. The page redirects to the previous page when the database already has a 'reaction_reacted' value of '1'.
Is there a way to solve this?
Here is an example of my code. The $promo_id, reaction_id and username are passed to it from the previous page when submission occurs.
session_start();
include 'connect.php';
mysql_connect($host,$db_user,$db_password);
mysql_select_db($database);
$promo_id = $_SESSION['promo_id'];
$reaction_id = $_SESSION[reaction_id];
$username = $_SESSION['username'];
if(isset($_SESSION['username']))
{
// Check to see if Receipt and DJID values are entered
$queryb = "select reaction_ID from reactiondata where reaction_ID='$reaction_id' AND reaction_username='$username' AND reaction_promoID='$promo_id' and reaction_reacted='1'";
$result2 = mysql_query($queryb) or die(mysql_error());
while($row = mysql_fetch_array($result2)){
header('Location: ' . $_SERVER['HTTP_REFERER']);
// session_destroy();
// exit;
}
if ($reaction_id && $promo_id != null)
{
$p4support = $_POST['DJsupport'];
$p4favouritemix = $_POST['FavMix'];
$p4score = $_POST['score'];
$p4comment = $_POST['DJcomment'];
$query = "UPDATE reactiondata SET reaction_username='$username', reaction_promoID='$promo_id', reaction_support='$p4support', reaction_favouritemix='$p4favouritemix', reaction_score='$p4score', reaction_comment='".mysql_real_escape_string($p4comment)."', reaction_reacted='1' WHERE reaction_ID='$reaction_id'";
mysql_query($query) or die('Error in MySQL query. Here is the error message: '.mysql_error());
$query7 = "UPDATE reactiondata SET reaction_time=NOW() WHERE reaction_ID='$reaction_id'";
mysql_query($query7) or die('Error in MySQL query. Here is the error message: '.mysql_error());
}
Thanks
CP
P.S I know I am using depreciated mysql_query methods, I just want the page to function properly before I start preventing SQL Injection attacks.
The easiest solution (one of the...) is to add the reaction_id as a hidden form field to the form instead of using a session. That way the reaction is always linked to the correct ID when the form is posted.
You should not use a session for that as the session will span all open windows and tabs in the browser so it is not suitable to maintain the state of a specific tab.

Use PHP to link to user profile

I want my php query to display the user name with a link to the user profile.
<?php
$get_items = "SELECT * FROM items WHERE category='test'";
$result = mysql_query($get_items);
while($item = mysql_fetch_array($result, MYSQL_ASSOC)){
$creator = $item['created_by'];
echo "<b>Seller: </b>"."<a href='userprof.php?id=$creator'>$creator</a>";
}
?>
Clicking on this link takes it to a user profile page that I created. But I want "userprof.php?id=$creator" to know which user to display the account information. Is this the best way to do this? How can I read the url and display the correct information?
<?php
$userId = $_GET['id'];
$sql = "SELECT * FROM user WHERE id = " . intval($userId);
$result = mysql_query($sql);
...
You are sending a GET variable.
$id = $_GET['id']; // Contains whatever was in $creator;
use $_GET for getting the variable from the URL.
like in your code you want to access the user profile then get the user id from url
like
http://localhost/test/user_profile.php?uid=2
here in the url uid is 2 thet is your userid.
you can get this id by using the code
$user_id = $_GET['uid'];
use this variable in your query.
OMG!! HORRIBLE PHP ABOUNDS! IT HURTS MY EYES!!
These people, none of them did both of the correct things:
ALWAYS FILTER USER INPUT!!
NEVER TRUST PHP ESCAPE FUNCTIONS, ESP NOT intval() and addslashes()!!
EVEN mysql_real_escape_string() HAS VULNERABILITIES AND SHOULD NEVER BE USED.
You should used prepared statements for everything in 2010.
Here it is the proper way:
<?php
if (!filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT))
{
trigger_error('Invalid User ID. It must be an integer (number).', PHP_USER_ERROR);
exit;
}
$userId = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$sql = "SELECT * FROM user WHERE id = ?";
$pdo = new PDO('mysql:host=localhost;db=mydb', $dbUsername, $dbPassWord);
$statement = $pdo->prepare($sql);
$statement->execute(array($userId));
$result = $statement->fetch(PDO::FETCH_ASSOC);
That is 100% secure. I hope people neither vote me down nor tone down my answer. Bad code is so systemic, we just have to shout from the rooftops until the new guys start learning it correctly, otherwise PHP as a professional language is seriously harmed.

Categories