Jump to content

Recommended Posts

My login script stores the user's login name as $_SESSION[ 'name'] on login. For some unapparent reason, i'm getting errors stating that $user  and $priv are  undefined variables, though I've attempted to define $user as being equal to $_SESSION['name'], using $user to look up the the user's privilege level (stored as the su column ) in the SQL table, and then where the result of the sql query is $priv which is then evaluated in an if statement. I can't seem to figure out why this might not be working.

The code I'm using:

<?php
session_start();
function verify() {
	//verify that the user is logged in via the login page. Session_start has already been called. 
	if (!isset($_SESSION['loggedin'])) {
	header('Location: /index.html'); 
	exit;
	}
	//if user is logged in, we then lookup necessary privleges. $_SESSION['name'] was written with the login name upon login. Privleges   // are written in db as a single-digit integer of of 0 for users, 1 for administrators, and 2 for special users. 
        $user === $_SESSION['name'];
    //Connect to Databse
	$link = mysqli_connect("127.0.0.1", "database user", "password", "database");
	if (!$link) {
  	  echo "Error: Unable to connect to MySQL." . PHP_EOL;
    	echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    	echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
    	exit;
        }
        //SQL Statement to lookup privlege information. 
       if ($result = mysqli_query($link, "SELECT su FROM accounts WHERE username = $user", MYSQLI_STORE_RESULT)) {
         //LOOP TO CYCLE THROUGH SQL RESULTS AND STORE Privlege information as vairable $priv.
            while ($row = $result->fetch_assoc()) {
           $priv === $row["su"];
            }
        }
        // close SQL connection.
        mysqli_close($link);

 // Verify privleges and take action. Only a privlege of "1" is allowed to view this page. A privlege of "2" indicates special 
//accounts used in other scripts that have certain indermediate additional functions, but are not trusted administrators. 

        if ($priv !== 1) {
        echo $_SESSION['name'];
        echo "you have privlege level of $priv";
        echo "<br>";
        echo 'Your account does not have the privleges necessary to view this page';
        exit;
        }
        
}
verify();
?>

 

8 minutes ago, Barand said:

I've read that- in fact it was my fist stop in approaching this- though I'm not sure how it applies here, as none of the examples there seem to be directly on point.

8 minutes ago, requinix said:

            while ($row = $result->fetch_assoc()) {
           $priv === $row["su"];
            }

What is that second line doing?

My first thought. (and it actually worked with the issue with $user, as I was able to successfully echo the variable to demonstrate it had been fixed.) However changing it to  $priv = $row['su'] still threw the same error, as if to say that SQL isn't properly returning $row['su'] at all- but if this were the case I'd expect an SQL error a )s opposed to variable undefined.

Edited by bakertaylor28
34 minutes ago, bakertaylor28 said:

as if to say that SQL isn't properly returning $row['su'] at all

Let's investigate that.

if ($result = mysqli_query($link, "SELECT su FROM accounts WHERE username = $user", MYSQLI_STORE_RESULT)) {

There's the query. Does it look like there might be anything wrong with it?

Try putting that string into a variable, echoing the variable so you can see the exact query, and running that query yourself manually.

"Quoted" is the term ("escaped" is like what you might do with backslashes) but yes: just like how strings in PHP need quotes around them, so do strings in SQL.

But adding quotes isn't enough because there's a risk the username will have something harmful in it. Use a prepared statement.

4 minutes ago, requinix said:

"Quoted" is the term ("escaped" is like what you might do with backslashes) but yes: just like how strings in PHP need quotes around them, so do strings in SQL.

But adding quotes isn't enough because there's a risk the username will have something harmful in it. Use a prepared statement.

Why do I need a prepared statement IF I'm not accepting user input, and the material already in the database was derived from a prepared statement? It would seem that a prepared statement isn't necessary here because, correct me if I'm wrong" injection  only concerns parsing user input into a database, not reading a database.

1 minute ago, bakertaylor28 said:

Why do I need a prepared statement IF I'm not accepting user input, and the material already in the database was derived from a prepared statement? It would seem that a prepared statement isn't necessary here because, correct me if I'm wrong" injection  only concerns parsing user input into a database, not reading a database.

It's not just about user input. It's about not knowing right there at that moment whether the value is safe. Can you guarantee that there is no possible way a username could have anything wrong with it? Not just in the database but also the value stored in the session?

Modern day "hacks" are not about finding a single problem that gives someone complete access. They're about finding a series of small vulnerabilities that combine to form something large. In your case, perhaps there's a way to get a username that's kinda invalid into the database, and then maybe there's a flaw in some code that loads the username into the session, and then maybe there's a flaw in this particular script where the bad username in the session can turn into SQL injection.

That's why application security is so difficult: to protect yourself you have to make sure that everything is covered, but for a malicious user all they have to do is find one or two problems.

  • Great Answer 1
16 minutes ago, requinix said:

It's not just about user input. It's about not knowing right there at that moment whether the value is safe. Can you guarantee that there is no possible way a username could have anything wrong with it? Not just in the database but also the value stored in the session?

Modern day "hacks" are not about finding a single problem that gives someone complete access. They're about finding a series of small vulnerabilities that combine to form something large. In your case, perhaps there's a way to get a username that's kinda invalid into the database, and then maybe there's a flaw in some code that loads the username into the session, and then maybe there's a flaw in this particular script where the bad username in the session can turn into SQL injection.

That's why application security is so difficult: to protect yourself you have to make sure that everything is covered, but for a malicious user all they have to do is find one or two problems.

I would have never really thought about it that way, in that I would have to double check the login script to make sure I'm not inadvertently setting a session var using post data. I'm still quite new to SQL though have dabbled a bit in php, though mostly have done content not involving databases until now. Thanks for your help.

3 hours ago, bakertaylor28 said:

login script to make sure I'm not inadvertently setting a session var using post data.

the username is a value that originally came from external submitted data. depending on your registration code's validation logic, it could contain anything, such as a hexadecimal encoded string, consisting of just letters and numbers (a hexadecimal encoded string, in a non-string context, will be decoded into whatever string it actually contains), or it could contain single-quotes, that if put directly into an sql query will allow sql injection.

it sounds like you think that using a prepared query ONCE, when the data was first submitted and stored makes the value safe to use in all future queries. it does not. it only made that first query safe.

any value that ever came from external, unknown, or dynamic data (recently, a year ago, or a year from now, when your application gets updated to get usernames via a call to an external api, where you don't know what type of characters it might contain) must treat the value as unsafe in whatever context the value is being used in (sql, html/css/javascript, email header, filename, system/shell, ...)

 

  • Great Answer 1
4 hours ago, mac_gyver said:

the username is a value that originally came from external submitted data. depending on your registration code's validation logic, it could contain anything, such as a hexadecimal encoded string, consisting of just letters and numbers (a hexadecimal encoded string, in a non-string context, will be decoded into whatever string it actually contains), or it could contain single-quotes, that if put directly into an sql query will allow sql injection.

it sounds like you think that using a prepared query ONCE, when the data was first submitted and stored makes the value safe to use in all future queries. it does not. it only made that first query safe.

any value that ever came from external, unknown, or dynamic data (recently, a year ago, or a year from now, when your application gets updated to get usernames via a call to an external api, where you don't know what type of characters it might contain) must treat the value as unsafe in whatever context the value is being used in (sql, html/css/javascript, email header, filename, system/shell, ...)

I was under the impression that a prepared statement acted in the same manner of permanency as a function such as htmlspecialchars - taking a permanent parameter binding when we call bindparam in the prepared statement. e.g. that the parameters remain bound for the rest of the statement any time you call SQL for the rest of the session.  Thanks for the correction.

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.