Solução
Nome | Valor |
---|---|
Vulnerabilidade | Broken Object Level Authorization (BOLA) |
CWE | CWE-639 |
OWASP Top Ten | A01_2021-Broken_Access_Control |
Métodos mágicos1 e suas
mágicas… Em uma instância da classe Request
no
Laravel, você pode ler o input do usuário
simplesmente tentando ler um atributo do objeto. Com isso,
ele irá ler o input da query string,
body ou o parâmetro da URL, caso
algum deles exista com esse nome. Do contrário retorna
null
.
Vejamos a implementação disso no Laravel 11:
/**
* Get an input element from the request.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{return Arr::get(
$this->all(),
$key,
fn () => $this->route($key)
;
) }
Sem entrar em detalhes de como
$this->all()
funciona, basicamente ele busca
pelo campo com aquele nome em todos os
inputs do usuário.
Exemplo: Se você ler o campo
$request->name
você não sabe como esse
name
foi enviado pelo usuário. Pode ser um
query parameter, pode ser um JSON no body,
pode ser um form parameter no body ou pode
ser o nome de um parâmetro da URL. O Laravel vai buscar por
um input chamado name
em qualquer um
desses lugares.
Ou seja, a validação feita em
UpdatePostRequest
está verificando se o usuário
tem permissão para editar o post de ID
$request->id
. Mas o controller
PostController
está editando o post de
ID $postId
, que é um parâmetro de URL… Mas e
$request->id
, é um parâmetro de URL também?
Ninguém sabe.
Tendo isso em mente, se a gente enviar na URL o ID do
post de outro usuário mas enviar o
ID de um post do nosso usuário em outro
input (ex.: no body), potencialmente o ID
validado em UpdatePostRequest
será diferente do
ID atualizado em PostController
.
Exemplo de requisição PUT /posts/2
:
{
"id": 1,
"title": "What is BOLA vulnerability?",
"content": "I dunno..."
}
Ou seja, efetivamente o post que será alterado
será o de ID 2
(na URL), mas a validação está
sendo feita com o ID 1
(no body).
Se você não sabe o que são métodos mágicos, sugiro que leia a documentação: https://www.php.net/manual/pt_BR/language.oop5.magic.php↩︎