0

I am using the PHP in_array() function in order to authenticate (with sessions) if a user can access a particular page. For some reason, it is not working...

PHP PAGE

session_start();
require_once('../scripts/functions.php'); 
$role_auth = @$_SESSION['role_auth'];
access($role_auth, array(0,1,2,3,4));

access FUNCTION

function access($role_auth, $array){

if(!(in_array($role_auth, $array))){ 
   header("Location: ../index.html");
}
}

If I insert print statements in the function, I can see that all of the correct values are being passed into the function. The problem is, if the function is called without a session variable set, for some reason it is considered as being in the array, and it authenticates.

Any ideas?

2
  • 3
    Just a tip, you can use range(0,4) instead of array(0,1,2,3,4). php.net/range Commented Jul 1, 2009 at 16:14
  • 2
    A quick note on your security check. Make sure you call die() or exit() after you send the header, because the content afterward in the script will still be send. Commented Jul 1, 2009 at 16:21

4 Answers 4

10

you may want to enable strict type checks by using:

in_array($role_auth, $array, true)

as what is likely happening is that $role_auth is being eval'd as false and that could match 0 in your in_array statement.

what you SHOULD be doing is this:

session_start(); 
require_once('../scripts/functions.php'); 
$role_auth = (isset($_SESSION['role_auth']))?$_SESSION['role_auth']:-1; 
access($role_auth, array(0,1,2,3,4));

or something similiar. nothing good ever comes of using the @ operator

Sign up to request clarification or add additional context in comments.

Comments

3

I would check to see if $_SESSION['role_auth'] is actually set (with isset) instead of using @ to suppress warnings (which is bad practice IMHO)

I think what's happening is that false == 0 ... so in_array returns true when nothing is in $role_auth because it sees it as 0 and 0 is in your array

Comments

3
 $role_auth = @$_SESSION['role_auth'];

The @ sign is suppressing any warnings you might get here, like index is not in array. How about something like this instead:

 if(isset($_SESSION['role_auth']))
    $role_auth = $_SESSION['role_auth'];
 else
    $role_auth = -1;//(or whatever an invalid role is)

1 Comment

The @ is also quite expensive when it comes to performance as php turns error reporting on and off in the background.
3

In php, the number zero is considered equal to most non-numeric things, for example:

null   == 0
false  == 0
""     == 0
"asdf" == 0

You probably need to make sure that $_SESSION actually contains the 'role_auth' key beforehand and convert it to the appropriate type, also passing the $strict parameter to in_array, thus guaranteeing a type check as well as a value check (=== vs. ==). Removing zero from your array might also be a good idea.

2 Comments

this surprises me!, 0 == "asdf" OMFG!! :@
HOLY SH#t!!, this behaviour affected my entire web app since was created! ( stock and serial codes related ), now i patched this and a consistency check was done... ( all is Ok! ) Seriously, i will nominate Noah Medling to Man of the Year =P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.