I am checking if the ID input is a not string and not null. Here is the code:
$id = $_POST["id"];
if(!is_string($id) && !empty($id)) {
$delete = mysqli_query($connect,"DELETE from users WHERE ID=$id");
$_SESSION["succMsg"] = "User have been successfully removed";
Header("Location:login_update.php");
} else {
$_SESSION["succMsg"] = "Unable to execute the query.";
Header("Location:login_update.php");
}
It somehow decides to not accept the query that I run. And I have no trouble when I remove the if statement. Though I want to check beforehand.
The issue is, that $_POST["id"]; always is a string - indeed all elements of the $_POST-array are - so is_string($id) of course returns true. What you really mean to do is to check, if it only consists of digits! ctype_digit($id) does this for example.
If your purpose is to migitate injection attacks, the easiest would probably be to cast it to an integer:
$id = (int) $_POST["id"];
Then it should work as you expect. The is_string($id) is of course unnecessary now. The is_empty() check should be performed before this assignment now (directly on $_POST["id"]). Maybe isset() is even more appropriate here, this eliminates for example a warning if id wasn't set as a parameter:
if (isset($_POST["id"])) {
$id = (int) $_POST["id"];
// Do your query....
}
Related
I searched almost whole internet, but could not find something similar, yet my question looks so simple.
I have a php code like so:
$id = 1;
if (!isset($_POST['port1'])) {
$port1 = null;
}
... which simply checks if submitted value is empty or not, if it is empty, then variable $port1 = null;
then, further in the code, I need to insert this value/update it in the database
$sql_update = ("UPDATE names_10 SET `digName1`=$port1 WHERE `device_id`='$id'");
...which should set the "digname1" to null. but it won't!
I tried every combination, every type of quotes, but every time I got UPDATE error..
any ideas?
Try this:
$id = 1;
if (!isset($_POST['port1'])) {
$port1 = "NULL";
}
$sql_update = ("UPDATE names_10 SET `digName1`= $port1 WHERE `device_id`='$id'");
I would rather suggest you to use PDO when you plan to bind something like this. There are a lot of benefits using PDO that would amaze you!
I'm trying to make an admin page and allow only users with role 2 for some reason its not giving me the information I expected.
<?php
session_start();
require_once('includes/mysql_config.php');
$id = isset($_SESSION['id']) ? $_SESSION['id'] : header('location: login.php');
$user = mysqli_query($con, "SELECT * FROM users WHERE id =".$_SESSION['id']) || false;
if($user['role'] == '2'){
echo "Hello $user['name']";
}
else {
header('location: index.php');
}
?>
When I do vardump($user) its giving me the output 1.
When I echo the $_SESSION['id'] it is giving me the right id (the session id is the same as user id).
Right now what you have done is, you just executed the query and had the resultset stored in $user. You need to fetch the results from the Result Set.
$user = mysqli_fetch_array($user);
Now it should work as expected.
Update: You should also handle the following:
Sanitization: Make sure you use ' for the values and ` for the column names. Also use mysqli_real_escape_string() for escaping some obvious stuff.
Validation: That's the next most important. Try checking if the resultset has any rows returned. You can do by using mysqli_num_rows($user) > 0 or precisely in your case, mysqli_num_rows($user) == 1.
Variables: Here in the example, I have used the same $user for the Result Set as well as the row. It is always better to have two separate variables, say, $userRes (for result set) and $userData (for the fetched data).
Hope this should answer your question.
After a successful select query mysqli_query() will return an mysqli_result object. You have to itterate over that to get your results. For example:
$user = mysqli_query($con, "SELECT * FROM users WHERE id =".$_SESSION['id']) || false;
if(user ){
// Cycle through results
while ($row = user ->fetch_object()){
$users[] = $row;
}
$user->close();
}
You're not fetching the results... If you check the manual, and look for the return value of mysqli_query(), you'll find:
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or
EXPLAIN queries mysqli_query() will return a mysqli_result object. For
other successful queries mysqli_query() will return TRUE
So go ahead and fetch it:
//$user = mysqli_query($con, "SELECT * FROM users WHERE id =".$_SESSION['id']) || false; // I'm unfamiliar with this || false stuff.
$result = mysqli_query($con, "SELECT * FROM users WHERE id =".$_SESSION['id']);
$user = mysqli_fetch_array($result);
It's also a good idea to sanitize your input (in order to prevent SQL-injection) and to check whether there are any results with mysqli_num_rows().
I am trying to check my database for a key that has already been put in. If the key exists then I need it to check to make sure the username field hasn't been filled. If it has then it needs to throw an error so that it doesn't update and overwrite the information already stored in the database.
Everything works. The update functions etc. the only part that does not work is the checking if the key exists and if the username portion is filled(not sure exactly how to do that) before updating the database.
Thanks,
Cameron Andrews
Code:
// If the Register form has been submitted
$err = array();
if(strlen($_POST['username'])<4 || strlen($_POST['username'])>32){
$err[]='Your username must be between 3 and 32 characters!';
}
if(preg_match('/[^a-z0-9 _]+/i',$_POST['username'])){
$err[]='Your username contains invalid characters!';
}
if(!checkEmail($_POST['email'])){
$err[]='Your email is not valid!';
}
$resultN = mysql_query("SELECT * FROM Users WHERE key='".$_POST['kgen']."'");
while($row = mysql_fetch_array($resultN))//for the results that are returned set the local variables
{
if($_POST['kgen'] == $row['key']){
if($_POST['username'] == $row['usr']){
$err[]='Username already in use';
}
}else if($_POST['kgen'] == ""){
$err[]='Invalid Key Code!';
}else{
$err[]='Error occured please try again';
}
}
if(!count($err)){
// If there are no errors
$_POST['email'] = mysql_real_escape_string($_POST['email']);
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['pass'] = mysql_real_escape_string($_POST['pass']);
// Escape the input data
$theName = $_POST['name'];
$theUser = $_POST['username'];
$thePass = $_POST['pass'];
$theEmail = $_POST['email'];
$theType = "member";
$theRegIP = $_SERVER['REMOTE_ADDR'];
$theDate = "NOW()";
$theKey = $_POST['kgen'];
// If everything is OK register
mysql_query("UPDATE cad.Users SET name = '$theName', usr = '$theUser', pass = '$thePass', email = '$theEmail', type = '$theType', regIP = '$theRegIP', dt = '$theDate' WHERE Users.key = '$theKey'");
Here is how I would approach it:
I would use mysqli or PDO instead of deprecated mysql functions.
I would rewrite all the queries to use prepared statements instead of concatenating your query string together - you have significant SQL injection vulnerability now.
But, since I am not going to rewrite your entire section of code for you, the rest of my approach will be described based on your current mysql/concatenated-query-string approach.
I would put a unique index on name field, but allow NULL value on the field.
I would simply run an update query rather than trying to run an unnecessary select plus an update.
UPDATE cad.Users
SET
name = '$theName',
usr = '$theUser',
pass = '$thePass',
email = '$theEmail',
type = '$theType',
regIP = '$theRegIP',
dt = NOW() /* don't pass 'NOW()' in single quotes as you are currently doing */
WHERE
Users.key = '$theKey'
AND User.name IS NULL;
If you get an error here you should look at error messaging to determine if update failed due to a unique constraint violation (user tried to enter a name that was already used in another record associated with a different key), or some other unexpected reason.
Assuming there was no error, I would then call mysql_affected_rows() (or appropriate equivalent in mysqli or PDO). If the return value is 1, an update was made. If the return value is 0, then no update was made because you did not have any rows that satisfied the WHERE condition.
If you get 0 affected rows, you can re-query the database if you really want to determine if the cause was no matching key or an existing user name.
SELECT name FROM Users WHERE key = '$theKey';
If you get no rows in the result it is because the key is missing, otherwise it is because the name was not a NULL value.
The net is that in the happy path use case, you only make a single query against the database rather than two, with two queries only being necessary if you want to determine the reason no update occurred for those cases. Your current approach always requires 2 queries.
First of all, you should see this. At second, i see, you have strange logic. Try to simplify it. :) As for me, i think it should looks like this:
<?php
if (strlen($_POST['username']) < 4 || strlen($_POST['username']) > 32) {
throw new RuntimeException('Your username must be between 3 and 32 characters!');
} elseif (preg_match('/[^a-z0-9 _]+/i', $_POST['username'])) {
throw new RuntimeException('Your username contains invalid characters!');
} elseif(!checkEmail($_POST['email'])) {
throw new RuntimeException('Your email is not valid!');
} elseif (empty($_POST['kgen'])) {
throw new RuntimeException('Invalid Key Code!');
}
$resultN = mysql_query("SELECT * FROM Users WHERE `key`='{$_POST['kgen']}' AND `usr`='{$_POST['username']}';");
$user = mysql_fetch_array($resultN);
if (!empty($user)) {
throw new RuntimeException('Username already in use');
}
// if all is fine - update
You can use exceptions for checking error. Benefit - you don't go to next check, if failed prev. You also have ability to show user exception message or reason(better use custom exception for this). Negative - you can't get list of errors.
I have this line in my registration page.
if (device_id_exists($_POST['device_id']) == true) {
$errors[] = 'Sorry the Serial Number \'' . htmlentities($_POST['device_id']) . '\' does not exist.';
}
I have this in my function page.
function device_id_exists($device_id) {
$device_id = sanitize($device_id);
$query = mysql_query("SELECT COUNT(`numbers`) FROM `devicenumbers` WHERE `numbers` = '$numbers'");
return (mysql_result($query, 0) == 0) ? true : false;
If I run this query SELECT COUNT(numbers) FROMdevicenumbersWHEREnumbers= '1234567890'
(a valid number) it will return 1 = match found right? If I put a bogus number it returns a '0'.
What is happening is when there is a valid number it still returns the error the number doesn't exist. If I change it to the result to == 1 it will submit any number? Im a newbie to DB calls any help appreciated. I hope I provided enough info.
Looks like you're calling the incorrect variable. Within the device_id_exists() function, you're accepting a variable named $device_id. However when you're performing the query, you're calling what appears to be an undefined variable: $numbers. I suspect $numbers should be renamed to $device_id.
I see your $device_id comes from a form post. I'd HIGHLY recommend you escape the variable, using mysql_real_escape_string() to ensure you are protected against SQL injection. Please note that sanitize() does NOT protect against SQL injection!
On one additional note, I'd recommend utilizng mysql_num_rows() rather than mysql_result() because mysql_result() actually asks the database server to return an actual result when all you really care about is whether the entry exists or not, not it's actual value.
function device_id_exists($device_id) {
$device_id = sanitize($device_id);
$device_id = mysql_real_escape_string($device_id);
$query = mysql_query("SELECT COUNT(`numbers`) FROM `devicenumbers` WHERE `numbers` = '$device_id'");
return mysql_num_rows($query) ? True : False;
}
I had a similar problem with mysql result set , It returns nums_rows == 1 even when there are no records (while using max() inside select query - In your case you have used count())... Instead of checking mysqlquery to 0, check it whether the result set empty (That's how i solved my problem).. eg. if(!empty(mysql_result($query))) ? true : false;
I want to add an edit button for a script called spiral url, but the problem is that I can't get the URL id. This is what I've tried:
/** get url id **/
$id = isset($_GET['id']) ? $_GET['id'] : '';
#mysql_query("UPDATE short_urls SET long_url = 'test' WHERE url_id = '".$id."' LIMIT 1");
What am I doing wrong?
Also I emailed the author and his response:
"I recommend you post on Stackoverflow - https://stackoverflow.com/.
I would love to help you but I don't see what you are doing wrong. I'm still learning PHP as well."
You're wide open to SQL injection attacks.
You're supressing errors with the # operator. NEVER suppress errors
You're not checking the return value of mysql_query(), which returns a boolean FALSE on failure.
Scrap that code and use this:
if (!isset($_GET['id'])) {
die("missing query parameter");
}
$id = intval($_GET['id']);
if ($id === '') {
die("Invalid query parameter");
}
$sql = "UPDATE short_urls SET long_url = 'test' WHERE url_id=$id LIMIT 1";
$result = mysql_query($sql);
if ($result === FALSE) {
die("Mysql error: " . mysql_error() . $sql);
}
Note that I'm assuming that the id parameter is numeric. If it's not, then remove the intval() stuff.
Make sure the value of $_GET['id'] actually has a value. Your URL will look something like http://myurl.com/index.phtml?id=yourvalue. You can do this by doing a:
print "id=".$_GET['id'];
Also, whenever doing a query, please be sure to escape any and all variables that can be manipulated by the user. Without doing this, you're opening yourself up to SQL injection attacks.
mysql_real_escape_string - http://php.net/manual/en/function.mysql-real-escape-string.php
#mysql_query("UPDATE short_urls SET long_url = 'test' WHERE url_id = '".mysql_real_escape_string($id)."' LIMIT 1");
If the url is like this: domain.com/something.php?id=65
$_GET['id'] should be equal to 65
if there is no id there then when you try to access $_GET['id'] you will get an error.
Also try removing the # symbol (that suppresses PHP warning).
And you are waaaay open to bobby-tables
Also (side note), get a new developer who knows what they are doing ;-)
Have you checked the url
http://www.somewebsite.com?id=56&other_car=test
specifically for the "?" after the end of the url and also check all the parts are broken up by the ampersand.
failing that you can view all of your available get array variables by
print_r($_GET);