Viewed   93 times

I have a login script that verifies a username/password against data in a 'user' table. Furthermore, I have a 'roles' table that specifies the access level of a given user. Assuming I am using safe login scripts, are there any security holes in simply performing an additional query, upon successful login, against the 'roles' table to discover the user's authorization level and storing this into a session variable? The idea would then be that on any page with mixed authority, I could simply query the session variable to discover the logged in user's authorization level.

Thanks.

 Answers

4

Sessions are significantly safer than, say, cookies. But it is still possible to steal a session and thus the hacker will have total access to whatever is in that session. Some ways to avoid this are IP Checking (which works pretty well, but is very low fi and thus not reliable on its own), and using a nonce. Typically with a nonce, you have a per-page "token" so that each page checks that the last page's nonce matches what it has stored.

In either security check, there is a loss of usability. If you do IP checking and the user is behind a intranet firewall (or any other situation that causes this) which doesn't hold a steady IP for that user, they will have to re-authenticate every time they lose their IP. With a nonce, you get the always fun "Clicking back will cause this page to break" situation.

But with a cookie, a hacker can steal the session simply by using fairly simple XSS techniques. If you store the user's session ID as a cookie, they are vulnerable to this as well. So even though the session is only penetrable to someone who can do a server-level hack (which requires much more sophisticated methods and usually some amount of privilege, if your server is secure), you are still going to need some extra level of verification upon each script request. You should not use cookies and AJAX together, as this makes it a tad easier to totally go to town if that cookie is stolen, as your ajax requests may not get the security checks on each request. For example, if the page uses a nonce, but the page is never reloaded, the script may only be checking for that match. And if the cookie is holding the authentication method, I can now go to town doing my evilness using the stolen cookie and the AJAX hole.

Sunday, August 21, 2022
2

I applaud your efforts. You must, friendly community member, consider decoupling your operations.

1) Have one function/routine/class/method for filtering input (filter_input_array(), strip_tags(), str_ireplace(), trim(), etc ...). You may want to create functions that use loops to do filtering. Tricks such as double encoding, one-time-strip-spoofing, and more can defeat single usage of things like strip_tags().

Here is a strip_tags() wrapper method from my Sanitizer class. Notice how it compares the old value to the new value to see if they are equal. If they are not equal, it keeps on using strip_tags(). Although, there is quite of bit of preliminary INPUT_POST / $_POST checking done before this method is executed. Another version of this using trim() is actually executed before this one.

private function removeHtml(&$value)
{    
    if (is_scalar($value)) {
        do {
            $old = $value;
            $value = strip_tags($value);

            if ($value === $old) {
                break;
            }
        } while(1);
    } else if (is_array($value) && !empty($value)) {
        foreach ($value as $field => &$string) {
            do {
                $old = $string;
                $string = strip_tags($string);

                if ($string === $old) {
                    break;
                }
            } while (1);
        }
    } else {
       throw new Exception('The data being HTML sanitized is neither scalar nor in an array.');
    }

    return;
}

2) Have another one for validating input (filter_var_array(), preg_match(), mb_strlen, etc...)

Then, when your data needs to switch contexts ...

A) For databases, use prepared statements (PDO, preferably).

B) For returning / transmitting user input to the browser, escape the output with htmlentities() or htmlspecialchars accordingly.

In terms of magic quotes, the best thing to do is just disable that in the php.ini.

Now, with those various constructs having their own areas of responsibility, all you have to do is manage the flow of logic and data inside of your handler file. This includes providing error messages to the user (when necessary) and handling errors/exceptions.

There is no need to use htmlentities() or htmlspecialchars immediately if the data is going from the HTML form directly into the database. The point of escaping data is to prevent it from being interpreted as executable instructions inside a new context. There is no danger htmlentities() or htmlspecialchars can resolve when passing data to a SQL query engine (that is why you filter and validate the input, and use (PDO) prepared statements).

However, after the data is retrieved from database tables and is directly destined for the browser, ok, now use htmlentities() or htmlspecialchars. Create a function that uses a for or foreach loop to handle that scenario.

Here is a snippet from my Escaper class

public function superHtmlSpecialChars($html)
{
     return htmlspecialchars($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}

public function superHtmlEntities(&$html)
{
    $html = htmlentities($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}

public function htmlSpecialCharsArray(array &$html)
{       
    foreach ($html as &$value) {
        $value = $this->superHtmlSpecialChars($value);
    }

    unset($value);
}

public function htmlEntitiesArray(array &$html)
{       
    foreach ($html as &$value) {
        $this->superHtmlEntities($value);
    }

    unset($value);
}

You'll have to tailor your code to your own personal tastes and situation.

Note, if you plan on processing the data before sending it to the browser, do the processing first, then escape with your handy-dandy htmlentities() or htmlspecialchars looping function.

You can do it!

Wednesday, October 12, 2022
 
sudoplz
 
4

This is probably because the register_globals directive is on. It doesn't say it on that page that $_SESSION variables are included, but it says here:

If register_globals is enabled, then the global variables and the $_SESSION entries will automatically reference the same values which were registered in the prior session instance. However, if the variable is registered by $_SESSION then the global variable is available since the next request.

Sunday, October 9, 2022
1

If you look closely to my answearin your previous question the very first thing mentioned (written in bold) was exactly this:

Maybe a session is started from a file that is included and this should not happen!

Vineet is correct and I will expand his right answear a bit more!

When you include the file child.php into the father.php you must think of the code found in child.php as being part of father.php One of the first things you do in a father.php script (like index.php) is a session start. You do not start a session in an included script because this might create some conflict as an other session could have been started already.

And if you have many files, (even worse if some of them are both included or executed directly cause of no single entry point) then how easy is to manage all this?!

You said this:

Thanks but the problem doesn't come from the structure of my site

Well this might not be entirely true! The thing is that writing old school code (no mvc, no single entry point, not really object oriented) has the benefit that has a very easy learning curve. HOWEVER while such code is easy to write the thing is that such code requires more skills to avoid errors!

On the other hand the object oriented aproach has more difficulty to get started cause there are more things to learn (objects, prototypes, interface, relatinships (belong-to, is part of) etc etc ) and requires a different behaviour. HOWEVER you definetely will benefit more!

A last thing! Well a well structred-site makes the session manage a thing of a few lines, writen only once at the very begining and that's it all.

I am glad that you are twoards solving you problem!

Tuesday, November 1, 2022
 
lokiare
 
1

If you are talking about someone else's server, then the short answer is no. If third parties could read your PHP source code, that would be quite a security hole, since PHP files tend to contain database passwords, hash keys, proprietary algorithms and other goodies that you don't want falling in the wrong hands.

If you are talking about your own server (ie. that you yourself have access to), then there are simple scripts that you can put on the server, that allow you to specify a path to any file on the server and have it returned as plaintext. However, you NEVER EVER want to place such a script on a production server, for the reasons mentioned above.

Monday, November 21, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :