> For the complete documentation index, see [llms.txt](https://stacked-rwx.gitbook.io/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stacked-rwx.gitbook.io/public/web-security/bypass-de-autenticacao-por-meio-de-php-type-juggling.md).

# Bypass de Autenticação por meio de PHP Type Juggling

Sejam bem vindos.

Segue abaixo o que eu vou apresentar nesse artigo.

* O que é Type Juggling?
* Como funciona?
* Qual o problema?
* Bypass de Autenticação
* Como corrigir?

*Por se tratar de uma vulnerabilidade pouco discutida em português (**pelo menos até onde eu pesquisei, não encontrei muitos artigos em português sobre o assunto**), o objetivo desta documentação é auxiliar desenvolvedores a evitar a criação de códigos vulneráveis e a identificar e mitigar esse tipo de problema.*

Então vamos pro que interessa!

## O que é Type Juggling? <a href="#id-861d" id="id-861d"></a>

De acordo com o [manual do PHP,](https://www.php.net/manual/en/language.types.type-juggling.php) o ‘[**Type Juggling**](https://www.php.net/manual/en/language.types.type-juggling.php)’ refere-se à conversão automática de tipos de dados entre diferentes tipos conforme necessário durante a execução do código. O manual do PHP aborda esse comportamento em várias seções, destacando como o PHP lida com a conversão implícita de tipos.

Por exemplo, se você usar uma string contendo um número em uma operação matemática, o PHP converterá essa string em um número automaticamente.

<figure><img src="/files/Qi40HDSfmvLF6JJDMMh7" alt=""><figcaption><p>Soma de String e Inteiro</p></figcaption></figure>

## Como funciona? <a href="#id-5a48" id="id-5a48"></a>

No PHP, existem dois modos principais de comparação, chamados operadores de comparação. Os dois operadores são: o operador de comparação flexível `==` e o operador de comparação estrito `===`.

Usando o operador de comparação flexível `==`, os desenvolvedores podem comparar valores mesmo que tenham tipos de dados diferentes, como inteiros e strings.

> **Mas espera aí! Esse tipo de conversão não ocorre mais a partir da versão PHP 8.0, certo? Até a versão PHP 7, esse tipo de conversão ainda é comum.**

## Qual o problema? <a href="#id-3154" id="id-3154"></a>

Um problema pode surgir quando o operador de comparação flexível é usado em locais inadequados, como sistemas de autenticação. Essa vulnerabilidade permite contornar o sistema de autenticação, já que não há uma validação adequada da entrada do usuário. Em vez disso, o Type Juggling altera automaticamente o tipo de dados de uma variável com base na entrada fornecida pelo usuário.

<figure><img src="/files/eqHicuO9e7DT3hNH0fjz" alt=""><figcaption><p>Docker com PHP 7.0.33</p></figcaption></figure>

Um exemplo bem interessante é quando o PHP compara alguma string que tenha um número com um inteiro.

<figure><img src="/files/f5edIviCY43iOMob5NC0" alt=""><figcaption><p>Comparação no PHP 7.0.33</p></figcaption></figure>

Basicamente nessa comparação, ele tentará extrair o inteiro da string, que no caso é o número 10. E como é de se esperar, essa comparação terá o resultado booleano “True”.

## Bypass de Autenticação <a href="#c196" id="c196"></a>

Então, diante desse problema, vamos examiná-lo em uma aplicação e ver como essa questão pode levar a uma vulnerabilidade de bypass na autenticação.

<figure><img src="/files/6dPMTs31OowkEddEySBY" alt=""><figcaption><p>Estrutura do sistema de autenticação</p></figcaption></figure>

Na função ‘**authenticate**’, temos um retorno onde são passadas as variáveis **$user\_input\_password** e **$stored\_password** como argumentos para a função **strcmp()**.

As variáveis são passadas como argumentos para a função `strcmp()`, que as compara. O operador `== 0` verifica se a comparação retorna 0, o que indica que as duas strings são iguais. No entanto, existe uma vulnerabilidade de Type Juggling. Se `$user_input_password` for um array, `strcmp($user_input_password, $stored_password)` retornará `null`, e a comparação `null == 0` resultará em `true`, permitindo um bypass na autenticação.

<figure><img src="/files/UpGDewK7xisxoRH5O7Rr" alt=""><figcaption><p>Passando Array ao invés de String</p></figcaption></figure>

<figure><img src="/files/qWInpKlP676xtcJC2ZsZ" alt=""><figcaption><p>Autenticação contornada com sucesso</p></figcaption></figure>

Comparar `null` com 0 usando `==` (`null == 0`) retorna `true` e podemos confirmar isso:

<figure><img src="/files/v1StC9QD0y0qm2fxEsWx" alt=""><figcaption><p>Comparação entre Null e 0</p></figcaption></figure>

Isso significa que se alguém passar um array vazio como a senha (`password[] = ""`), a comparação pode ser erroneamente considerada bem-sucedida, permitindo um bypass na autenticação.

## Como corrigir? <a href="#caeb" id="caeb"></a>

Bom, para corrigir esse problema, existem duas formas:

* A primeira delas é trocando o operador de comparação flexível pelo operador de comparação estrito:

<figure><img src="/files/mKszsIYRmCkPupYgznzL" alt=""><figcaption><p>Operador de comparação estrito ===</p></figcaption></figure>

O operador de comparação estrito `===` em PHP é diferente do operador de comparação flexível `==` porque ele verifica tanto o valor quanto o tipo dos operandos. Isso elimina o Type Juggling, que é a conversão automática de tipos de dados.

* E a segunda forma é garantir que os dados enviados são strings. Para isso, podemos validá-los da seguinte maneira:

<figure><img src="/files/tV7KjxVtLtM11bUwDgjt" alt=""><figcaption><p>Função is_string() para validar se a entrada é uma String</p></figcaption></figure>

Diante disso, obtivemos o seguinte resultado após a correção:

<figure><img src="/files/jHqNjsL6tWn2UDr7iqAF" alt=""><figcaption><p>Resultado após a correção</p></figcaption></figure>

Ele nos redirecionou de volta para o formulário de login depois de tentar enviar um array como senha.

A ideia desta documentação é explicar como o Type Juggling pode levar a problemas sérios quando utilizado incorretamente, especialmente em sistemas de autenticação. Meu objetivo é conscientizar e incentivar os desenvolvedores a buscarem conhecimento em segurança, a fim de evitar que tais situações ocorram.

Até mais!

\~ Rafael Romão
