> ## Content Index
> Fetch the complete content index at: https://securinglaravel.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Security Tip: Watch Out for Type Juggling
- URL: https://securinglaravel.com/security-tip-type-juggling/
- Published: 2022-06-30T03:00:21.000Z
- Updated: 2024-12-04T00:00:36.000Z
- Description: [Tip#26] Type Juggling is still very much a problem.
- Author: Stephen Rees-Carter
- Tags: Security Tips, Type Juggling

PHP and type juggling…

In my opinion, type juggling is one of PHP’s strengths, but it can also one of PHP’s easily exploitable weaknesses.

The weakness is the result of using a loose comparison ( `==` and `!=` ), rather than a strict comparison ( `===` and `!==` ), and if I can impart just one thing from this post, it’s a reminder to **always use a strict comparison**, unless you specifically need a loose comparison. You also need to be aware of which functions are strict and loose, and code accordingly.

> **Important note:** If you’re comparing sensitive strings like API keys or passwords, you really should use the `hash_equals()` method. It ensures a type and timing safe comparison. [I wrote about it here!](https://securinglaravel.com/security-tip-compare-keys-with-hash%5Fequals/)

Being vulnerable to type juggling is a common argument used against PHP and it was such a big concern that [PHP 8 introduced a backwards incompatible change](https://www.php.net/manual/en/migration80.incompatible.php?ref=securinglaravel.com) that changed *string-to-number* comparisons so they would convert to strings and not numbers.

This should show you the before and after behaviour:

```
Comparison      PHP 7.4 and earlier    PHP 8.0+
0 == "0"        true                   true
0 == "0.0"      true                   true
0 == "foo"      true                   false
0 == ""         true                   false
42 == " 42"     true                   true
42 == "42foo"   true                   false
```

While this was a great security update to PHP, it didn’t solve the whole problem. Sure you can no longer easily juggle numbers and strings maliciously, but there are more inputs you can provide that you still can juggle with.

For example: **Booleans!**

The easiest way to exploit type juggling is through an API endpoint, because you’re not limited to passing everything in as a string. Instead, you can submit a Boolean directly to the API and the code will see it as one.

**Let’s take a look at a super simple example:**

```
Route::post('test', function (Request $request) {
    return [
        '$request->input' => $input = $request->input,
        "'string' == \$input"  => 'string' == $input,
        "'string' != \$input"  => 'string' != $input,
        "'string' === \$input" => 'string' === $input,
        "'string' !== \$input" => 'string' !== $input,
    ];
});
```

Using the above API route, let’s send some `true` and `false` values:

```
>>> Http::post('https://larasec/api/test', [
    'input' => true,
])->json();
=> [
     "$request->input" => true,
     "'string' == $input" => true,
     "'string' != $input" => false,
     "'string' === $input" => false,
     "'string' !== $input" => true,
   ]

>>> Http::post('https://larasec/api/test', [
    'input' => false,
])->json();
=> [
     "$request->input" => false,
     "'string' == $input" => false,
     "'string' != $input" => true,
     "'string' === $input" => false,
     "'string' !== $input" => true,
   ]
```

You’ll note that passing in the Boolean value `true` allows us to pretend we’ve passed in a valid string:

```
'string' == $input  => true
'string' != $input  => false
```

In this example, we’ve got an API checking a string value, but what if that string value is the API authentication key that provides access to the API?

We’ve bypassed the auth key by passing `true` instead… Full access granted, no API key required. 😱

> *I have found this exact vulnerability in a number of my security audits. An auth token is received by the app via a JSON payload, swapping it to* `true` *instantly gave me access. Every. Single. Time. I even did it via a cookie once.* 😈

**Do you do this in your app?**

Type juggling is a problem, and it’s not just limited to Boolean values and API endpoints. Check your app to ensure you’re doing strict comparisons and validate & typecast inputs to ensure they are in the formats you need.

---

***If you found this security tip useful,*** [***subscribe***](#/portal/signup) ***to get weekly*** [***Security Tips***](https://securinglaravel.com/tag/tips/) **straight to your inbox.* Upgrade to a* [*premium subscription*](#/portal/signup) *for exclusive monthly* [*In Depth articles*](https://securinglaravel.com/tag/in-depth/)*, or drop a coin in the* [*tip jar*](#/portal/support) *to show your support.*

*Looking for a* [*Laravel Security Audit / Penetration Test*](https://stephenreescarter.net/laravel-security-audits-and-pentesting/?utm%5Fsource=securinglaravel.com)*, or a budget-friendly* [*Security Review*](https://stephenreescarter.net/laravel-security-reviews/?utm%5Fsource=securinglaravel.com)*? Feel free to reach out! You can also connect with me on* [*Bluesky*](https://bsky.app/profile/valorin.bsky.social?ref=securinglaravel.com)*, or* [*other socials*](https://pinkary.com/@valorin?ref=securinglaravel.com)*. And don’t miss* [*Practical Laravel Security*](https://practicallaravelsecurity.com/?utm%5Fsource=securinglaravel.com)*, my interactive course designed to boost your Laravel security skills.*