vote up 0 vote down star

Hey everyone,

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?

flag

75% accept rate
2  
Just a tip, you can use range(0,4) instead of array(0,1,2,3,4). php.net/range – tj111 Jul 1 at 16:14
1  
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. – merkuro Jul 1 at 16:21

4 Answers

vote up 7 vote down check

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

link|flag
+1 for the evil @ tip – Luiz Damim Jul 1 at 16:21
vote up 3 vote down

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

link|flag
vote up 3 vote down
 $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)
link|flag
The @ is also quite expensive when it comes to performance as php turns error reporting on and off in the background. – Kimble Jul 1 at 23:17
vote up 1 vote down

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.

link|flag

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.