Skip to content
This page has been auto-translated and may contain errors.View in English

Autenticação vs autorização

Toda requisição que um usuário faz levanta duas perguntas, e elas são respondidas em ordem.

Quem é essa pessoa? e o que ela pode fazer?

A primeira é autenticação. A segunda é autorização. As duas costumam ser chamadas de "auth", as duas começam com as mesmas seis letras, e resolvem problemas completamente diferentes.

Provando quem você é

A autenticação responde a uma única pergunta: essa pessoa é mesmo quem diz ser?

Você já conhece os métodos comuns como usuário:

  • Um nome de usuário e uma senha.
  • Fazer login com o Google ou o GitHub.
  • Enviar uma API key ou um token junto com a requisição.

Cada um desses é uma forma de apresentar evidências. O trabalho do servidor é decidir se essas evidências se sustentam.

Se isso for feito errado, alguém pode se passar por outra pessoa. Isso é spoofing, o S do STRIDE, e é a falha que torna qualquer outra proteção irrelevante, porque a aplicação passa a aplicar as regras certas para a pessoa errada.

JunoProvando quem você é Ajuda pensar na autenticação como a porta, e em tudo o que vem depois como o que você pode tocar depois de entrar.

A porta não se importa com o que você quer fazer. O único trabalho dela é decidir se você é mesmo a pessoa que diz ser.

JunoProvando quem você é Vale a pena acertar os status codes, porque os nomes deles enganam. Um 401 se chama Unauthorized, mas na verdade significa não autenticado: não sabemos quem você é, então faça login. Um 403 é Forbidden e significa que sabemos exatamente quem você é e mesmo assim você não pode fazer isso.

Enviar um 403 quando o usuário não tem nenhuma sessão diz ao cliente para desistir, quando o certo seria pedir um login.

JunoProvando quem você é A distinção importante de guardar é que a autenticação acontece uma vez por sessão e gera uma alegação (claim), enquanto a autorização acontece em cada requisição e consome essa alegação. A maioria dos bugs de identidade é, na verdade, sobre quanto tempo essa alegação continua sendo confiada depois que os fatos por trás dela mudaram.

Vale separar uma terceira palavra que costuma ser misturada. Identificação é apresentar uma alegação, autenticação é prová-la, e responsabilização (accountability) é mostrar depois quem fez o quê.

O STRIDE dá ao repúdio uma letra própria justamente porque um sistema pode autenticar corretamente e ainda assim ser incapaz de demonstrar depois quem executou uma ação.

Decidindo o que você pode fazer

A autorização acontece depois, e só faz sentido depois que a identidade já está definida:

  • Um usuário lendo os próprios dados.
  • Um usuário atualizando o próprio perfil.
  • Um professor lendo os registros dos seus alunos.
  • Essa mesma requisição feita por um aluno, recusada.

Se isso for feito errado, as pessoas fazem coisas que não deveriam. No STRIDE isso é elevação de privilégio; na OWASP Top 10 isso é controle de acesso quebrado, que está no topo da lista há anos.

JunoDecidindo o que você pode fazer Repare que a mesma pessoa recebe respostas diferentes dependendo do que ela está pedindo.

Estar logado não é uma permissão única. É o ponto de partida para uma pergunta separada, feita de novo a cada requisição.

JunoDecidindo o que você pode fazer O bug comum é verificar se alguém está logado e parar por aí. Uma rota que carrega um registro pelo id e o devolve para qualquer usuário autenticado tem autenticação e nenhuma autorização.

A pergunta a fazer sobre todo handler que recebe um id: ele confirma que esse usuário é dono desse registro? Quando a resposta é não, essa brecha tem nome: uma referência direta insegura a objeto (insecure direct object reference), e é a forma mais comum que o controle de acesso quebrado assume.

JunoDecidindo o que você pode fazer Onde a decisão mora importa mais do que como ela é expressa. Verificações espalhadas pelos handlers vão se desalinhando com o tempo, e a única rota que esqueceu fica invisível até alguém encontrá-la.

Os padrões que se sustentam centralizam a decisão: uma camada de política que a rota consulta, ou uma camada de dados que não consegue devolver linhas às quais quem chamou não tem direito. Os dois tornam a pergunta "quais endpoints verificam propriedade" respondível lendo um único lugar.

Um botão escondido não é autorização. É uma cortesia para usuários honestos, exatamente como a validação no navegador, e a rota por trás dele continua respondendo a qualquer um que a chame diretamente.

A ordem em que elas acontecem

Toda requisição que chega a um recurso protegido passa pelas duas, na mesma sequência:

text
request  ──▶  authentication  ──▶  authorization  ──▶  resource
              (who are you?)      (may you do this?)

Dois exemplos deixam isso claro. Um usuário lendo o próprio perfil: a requisição chega, a autenticação estabelece quem ele é, a autorização confirma que o perfil pertence a ele, o acesso é concedido.

Um administrador acessando um endpoint só para administradores: a requisição chega, a autenticação estabelece quem ele é, a autorização verifica se ele tem privilégios de administrador, o acesso é concedido.

Apenas uma das quatro etapas muda entre esses dois casos. A verificação de identidade é idêntica, e a verificação de permissão é onde as duas requisições se separam.

Autenticação forte com autorização fraca é inseguro. Autorização forte sem autenticação sólida não tem sentido.

JunoA ordem em que elas acontecem A ordem não é uma convenção, é uma dependência. Você não pode decidir o que alguém pode fazer antes de saber quem essa pessoa é.

É por isso que a autenticação vem sempre primeiro, e por que um erro nela desmancha tudo o que vem depois.

JunoA ordem em que elas acontecem Em uma aplicação Express, as duas etapas são middlewares, e a ordem na cadeia é a ordem do diagrama. Uma verificação de autorização colocada antes da de autenticação roda contra um usuário que ainda não foi identificado.

A ordem dos middlewares é comportamento, não apenas organização, e vale a pena lembrar disso quando uma rota para de funcionar depois que alguém reorganiza sua definição.

JunoA ordem em que elas acontecem Fique atento a decisões de autorização tomadas com base em uma identidade desatualizada. Uma sessão ou token estabeleceu a alegação (claim) no login, e o papel (role) associado a ela pode estar minutos ou horas desatualizado quando uma requisição chega.

Se essa defasagem é aceitável ou não é a troca (tradeoff) por trás de todo modelo de identidade nesta seção. Sessões mantidas no servidor podem ser atualizadas ou destruídas instantaneamente. Tokens autocontidos não podem, e é por isso que o token de um funcionário demitido continua funcionando até expirar.

Essa é uma decisão de design, não um detalhe de implementação, e é o motivo pelo qual os próximos capítulos tratam de onde a identidade mora.

Coloque em prática

Quatro situações. Para cada uma, decida se a falha é de autenticação ou de autorização, e diga a que letra do STRIDE ela corresponde.

  1. Um formulário de login aceita qualquer senha para o nome de usuário admin.
  2. Um cliente logado muda o id em uma URL e vê o pedido de outro cliente.
  3. Um endpoint de API aceita requisições sem nenhum token.
  4. Um agente de suporte consegue excluir contas, algo que só deveria ser possível para administradores.
Compare suas respostas
#FalhaPor quêSTRIDE
1AutenticaçãoA aplicação não consegue saber quem está no teclado, então qualquer um pode se passar por adminSpoofing
2AutorizaçãoO cliente realmente é quem diz ser; nada verificou se o pedido pertence a eleElevação de privilégio
3AutenticaçãoNenhuma alegação é apresentada, então o endpoint não tem ideia de quem está chamando. Um 401 é a resposta corretaSpoofing
4AutorizaçãoO agente é identificado corretamente e a verificação de permissão está errada. Um 403 é a recusa corretaElevação de privilégio

O número 2 tem nome próprio: uma referência direta insegura a objeto. Em termos da OWASP, tanto o 2 quanto o 4 são controle de acesso quebrado.

Dois e quatro são a mesma classe de bug vestindo roupas diferentes, o que é parte do motivo pelo qual o controle de acesso quebrado continua no topo da lista da OWASP. Nos dois casos, a aplicação sabia exatamente quem estava perguntando.

Para onde isso vai a partir daqui

A autenticação acontece uma vez, no login. A autorização acontece em toda requisição depois disso, e precisa saber quem é o usuário a cada vez.

O que deixa uma lacuna incômoda, porque o HTTP não guarda memória nenhuma de uma requisição para a próxima.

Como as aplicações lembram de você é o problema que essa lacuna cria, e as três famílias de resposta que o restante desta seção percorre.