PHP — Type Juggling

SickAndTired
System Weakness
Published in
3 min readJan 17, 2023

--

Type Juggling it’s a kind of bug that occurs only on PHP, mainly due to the way the language “compares” one thing to another.

In PHP there’re a pair of operators that, although look similar, they do perform different tasks, those are == and ===.

Double equals essentially evaluate if the variable, or whatever being compared, is empty or not. We can see that on the first condition, which “verifies” if $txt is really empty or not. The result obviously gonna be Truesince $txtis not empty at all.

However, there’s another way to do that, and that is with double equals. Take a look at the second comparison which basically checks if $txt is equals to nothing, or “empty” in another words, if it really is, is gonna echo Empty!! if it’s not, well… True.

However, double equals might be a problem, since the user can juggle it. Bbecause ==just checks the content of what’s being evaluated, not its type. That might sound confusing, but let’s go one step at a time.

First, let’s understand how it work the assignment of a Boolean to a variable. When we assign False to $txt and print it, we see that it actually prints nothing at all. On the other hand, we can see that if we assign True the echo outputs is 1.

That’s been said, let’s see how someone could potentially trick a comparison mechanism which use double equals.

Imagine a condition that checks whether a password is the right one or not. On the first case, we assign to the $password variable thepass123 value. As a result, the condition is not met and consequently doesn’t print Access Granted.

But if we assign Trueto $passwordand repeat the comparison, we actually succeed, because true will always result in true.

That happens, due the fact that double equals only check the content of the variable being compared with something else, but true will always result in true.

That could lead to some bypass depending on the application functionaity.

Let’s take a look at this snippet of code from base box.

if (!empty($_POST['username']) && !empty($_POST['password'])) {                                           
require('config.php');
if (strcmp($username, $_POST['username']) == 0) {
if (strcmp($password, $_POST['password']) == 0) {
$_SESSION['user_id'] = 1;
header("Location: /upload.php");
} else {
print("<script>alert('Wrong Username or Password')</script>");
}
} else {
print("<script>alert('Wrong Username or Password')</script>");
}

It’s basically checking, with strcmp, if the provided usernameand password “equals” the ones stored at theconfig.phpfile. If that comparison results in 0 then the “ifs” are satisfied.

That could easily be bypassed by providing an empty array for username and password.

Then we successfully bypass the login form.

In case of comprisons, the best approach is to implement it in a strict way, that’s why PHP has triple equals, which compares both dataand type to whatever is being compared.

Useful resources

Owasp — Type Juggling

Ippsec — Type Juggling

--

--