Como o OAuth 2 se protege contra ataques de repetição usando o token de segurança?

564

Pelo que entendi, a seguinte cadeia de eventos ocorre no OAuth 2 Site-Apara acessar as informações do Usuário de Site-B.

  1. Site-Aregistra Site-Be obtém um segredo e um ID.
  2. Quando o usuário pede Site-Apara acessar Site-B, o usuário é enviado para Site-Bonde eles dizem Site-Bque realmente gostariam de dar Site-Apermissões a informações específicas.
  3. Site-Bredireciona o usuário de volta para Site-A, junto com um código de autorização.
  4. Site-Aem seguida, passa esse código de autorização juntamente com seu segredo de volta Site-Bem troca de um token de segurança.
  5. Site-Aem seguida, solicita Site-Bem nome do Usuário agrupando o Token de Segurança junto com os pedidos.

Como tudo isso funciona em termos de segurança e criptografia, em alto nível? Como o OAuth 2 se protege contra ataques de repetição usando o token de segurança?

William Jones
fonte
49
oauth2 simplesmente explicou aqui: gist.github.com/mziwisky/10079157
Paolo
4
Leia a especificação: tools.ietf.org/html/rfc6749 Você pode se surpreender com o quão compreensível é. Também é correto, o que pode não ser muito ruim.
Kris Vandermotten
1
Esta pergunta e suas respostas (atuais) concentram-se em um "tipo de concessão" específico no OAuth 2.0 (ou seja code), mas existem outros tipos de concessão definidos no OAuth 2.0 que são relevantes para diferentes casos de uso (por exemplo, não relacionados ao usuário).
Hans Z.
4
Ah, por que não substituir o "Site B" por algo mais legível como "IdProvider Site"?
Yurii

Respostas:

1378

Como o OAuth 2.0 funciona na vida real:

Eu estava dirigindo pela padaria de Olaf, no meu caminho para o trabalho, quando vi a rosquinha mais deliciosa na janela - quero dizer, a coisa estava pingando um sabor chocolate. Então entrei e exigi "Devo ter essa rosquinha!". Ele disse "com certeza serão US $ 30".

Sim, eu sei, US $ 30 por uma rosquinha! Deve ser uma delicia! Peguei minha carteira quando, de repente, ouvi o chef gritar "NÃO! Sem rosquinha para você". Eu perguntei: por que? Ele disse que só aceita transferências bancárias.

A sério? Sim, ele estava falando sério. Eu quase me afastei ali mesmo, mas o donut me chamou: "Coma-me, estou delicioso ...". Quem sou eu para desobedecer ordens de um donut? Eu disse ok.

Ele me entregou uma nota com o nome dele (o chef, não o donut): "Diga a eles que Olaf lhe enviou". Seu nome já estava na nota, então não sei qual era o sentido de dizer isso, mas tudo bem.

Eu dirigi uma hora e meia para o meu banco. Entreguei o bilhete para o caixa; Eu disse a ela que Olaf me enviou. Ela me deu um desses olhares, do tipo que diz: "Eu sei ler".

Ela pegou minha nota, pediu minha identidade, perguntou quanto dinheiro havia para lhe dar. Eu disse a ela $ 30 dólares. Ela fez alguns rabiscos e me entregou outra nota. Este tinha muitos números, imaginei que eles controlassem as anotações.

Nesse ponto, estou morrendo de fome. Saí correndo dali, uma hora e meia depois estava de volta, de pé em frente a Olaf com a nota estendida. Ele pegou, olhou e disse: "Volto".

Eu pensei que ele estava pegando minha rosquinha, mas depois de 30 minutos comecei a suspeitar. Então eu perguntei ao cara atrás do balcão "Cadê Olaf?". Ele disse: "Ele foi buscar dinheiro". "O que você quer dizer?". "Ele toma nota no banco".

Huh ... então Olaf anotou que o banco me deu e voltou ao banco para tirar dinheiro da minha conta. Como ele recebeu a nota que o banco me deu, o banco sabia que ele era o cara de quem eu estava falando, e porque eu conversei com o banco, eles sabiam que só lhe davam 30 dólares.

Deve ter demorado muito tempo para descobrir isso, porque quando olhei para cima, Olaf estava parado na minha frente, finalmente me entregando minha rosquinha. Antes de sair, tive que perguntar: "Olaf, você sempre vende rosquinhas dessa maneira?". "Não, eu costumava fazer diferente."

Hã. Enquanto eu voltava para o meu carro, meu telefone tocou. Eu não me incomodei em responder, provavelmente era meu trabalho ligar para me demitir, meu chefe é um idiota. Além disso, fui pego pensando no processo que acabei de passar.

Quero dizer, pense: pude deixar Olaf tirar US $ 30 da minha conta bancária sem precisar fornecer as informações da minha conta. E eu não precisava me preocupar que ele gastasse muito dinheiro, porque eu já disse ao banco que ele só podia receber US $ 30. E o banco sabia que ele era o cara certo, porque ele tinha a nota que eles me deram para dar a Olaf.

Ok, com certeza eu prefiro entregar $ 30 a ele do meu bolso. Mas agora que ele tinha esse bilhete, eu podia dizer ao banco para deixá-lo levar US $ 30 por semana, então eu poderia aparecer na padaria e não precisava mais ir ao banco. Eu poderia até pedir o donut por telefone, se quisesse.

É claro que eu nunca faria isso - esse donut era nojento.

Gostaria de saber se essa abordagem tem aplicações mais amplas. Ele mencionou que essa era sua segunda abordagem, eu poderia chamar de Olaf 2.0. De qualquer forma, é melhor eu chegar em casa, tenho que começar a procurar um novo emprego. Mas não antes que eu pegue um daqueles batidos de morango daquele novo lugar na cidade, preciso de algo para lavar o sabor desse donut.

Luis Perez
fonte
41
Bem, na prática, Olaf deve poder tirar US $ 30 da sua conta sempre que quiser, mesmo que você não peça nenhuma rosquinha. Curiosamente, esse é o objetivo principal nos cenários reais do oauth2.0 :) Essa é certamente uma ótima resposta, mas quem estiver lendo isso, vá para o git gist que Paolo mencionou em seu comentário à pergunta ( gist.github.com/mziwisky/ 10079157 ). Uma boa leitura complementar para tornar o conceito claro.
Samiron
4
Ótima resposta, mas dois pontos a serem levantados: 1. Como @Samiron apontou, Olaf poderia receber 30 $ sempre que quisesse. 2. Em um cenário real do OAuth2.0, o Olaf não poderá servir a rosquinha antes de tirar dinheiro do banco. Enquanto neste exemplo, ele poderia ter ficado com o cheque e simplesmente entregado a Luis sua merecida rosquinha. Portanto, se alterarmos o exemplo para autorizar Olaf a receber massa de terceiros que conheço, faria mais sentido, pois Olaf teria que obter a massa antes que ele começasse a assar o donut (assumindo o donut solitário Olaf tinha apenas para fins de exibição!).
Ticker23
4
ticker23, infelizmente, a história da rosquinha supera sua correção técnica - eu fui vendida na história quando a li. Foi escrito por Homer Simpson.
shevy
4
@Prageeth Olaf sempre carrega a nota de e para o banco em uma caixa segura que vaza tinta se for adulterada, levaria muitas vidas para restaurar a nota. O banco também tira impressões digitais dos clientes em sua primeira visita, se Olaf perder os dedos em um acidente de cozimento, ele terá que pedir a Luis para configurar a transferência bancária novamente, e o banco terá que identificar Olaf por sua tatuagem Breaking Bread na próxima vez .
Chris
11
Eu amo respostas fofas tanto quanto a próxima pessoa, e quando a fofura delas ajuda a tornar a resposta mais acessível, isso é incrível ... mas no final do dia, o Stack Overflow é sobre educar as pessoas, e essa história fofa não faz isso. Para entender a analogia da rosquinha, você já deve entender como o OAuth2 funciona, mas o ponto principal da resposta era explicar exatamente isso. Por favor, considere editar esta resposta (superior) para realmente explicar os conceitos, não apenas referenciá-los obliquamente no final ... mesmo que isso ocorra ao custo de uma ou duas piadas.
precisa
133

Com base no que li, é assim que tudo funciona:

O fluxo geral descrito na pergunta está correto. Na etapa 2, o Usuário X é autenticado e também está autorizando o acesso do Site A às informações do Usuário X no Site B. Na etapa 4, o site transmite seu Segredo de volta ao Site B, autenticando-se, bem como o Código de Autorização, indicando o que está pedindo (token de acesso do usuário X).

No geral, o OAuth 2 é realmente um modelo de segurança muito simples, e a criptografia nunca entra diretamente em ação. Em vez disso, o segredo e o token de segurança são essencialmente senhas, e a coisa toda é protegida apenas pela segurança da conexão https.

OAuth 2 não tem proteção contra ataques de repetição do token de segurança ou do segredo. Em vez disso, depende inteiramente do Site B ser responsável por esses itens e não deixá-los sair, além de serem enviados por https enquanto estiverem em trânsito (https protegerá os parâmetros de URL).

O objetivo da etapa do código de autorização é simplesmente a conveniência, e o código de autorização não é especialmente sensível por si só. Ele fornece um identificador comum para o token de acesso do Usuário X para o Site A ao solicitar ao Site B o token de acesso do Usuário X. Apenas a identificação de usuário do usuário X no site B não funcionaria, pois poderia haver muitos tokens de acesso pendentes aguardando a entrega a sites diferentes ao mesmo tempo.

William Jones
fonte
28
Você ignorou uma função importante do código de autorização. Por que não retornar o token de atualização (o que você chama de Token de Segurança) imediatamente, em vez de ter a etapa extra de trocar o código de autorização por ele? Como a captura do token de atualização permitiria ataques de repetição, enquanto o código de autorização pode ser usado apenas uma vez.
Maurice Naftalin
3
OK, @mauricen, isso faz sentido ... Mas o ataque de repetição não poderia acontecer tão bem com o token de atualização, já que é isso que acaba sendo passado com cada solicitação?
Mikkél
15
O código de autorização é passado pelo usuário, portanto (por exemplo) pode ser armazenado como um cookie (consulte stackoverflow.com/questions/4065657/… ). O token de atualização passa diretamente entre os dois sites, portanto, é muito menos vulnerável.
Maurice Naftalin
Por curiosidade, o OAuth retorna algum identificador exclusivo para o programa usar? Por exemplo, atualmente estou contando com o endereço MAC para identificação do usuário, mas com isso dito, os MACs não são confiáveis ​​/ são facilmente protegidos / etc. Eu posso simplesmente descartar o mecanismo de identificação de endereço MAC e usar o OAuth se ele me permitir identificar usuários de maneira exclusiva.
theGreenCabbage
1
Observe neste diagrama: tools.ietf.org/html/rfc6749#section-4.1 que o "Segredo" não é mostrado, apenas o Identificador do Cliente (ID na pergunta). Por que o segredo é importante e por que não está incluído na RFC? Também na questão, há também o estado local recomendado para ser transmitido na transmissão inicial do ID do cliente (A) e o redirecionamento de volta ao cliente junto com o código de autorização para proteção contra o XSSF.
David Williams
104

OAuth é um protocolo com o qual um aplicativo de terceiros pode acessar seus dados armazenados em outro site sem sua conta e senha. Para uma definição mais oficial, consulte o Wiki ou especificação.

Aqui está uma demonstração de caso de uso:

  1. Eu entro no LinkedIn e quero conectar alguns amigos que estão nos meus contatos do Gmail. O LinkedIn suporta isso. Ele solicitará um recurso seguro (minha lista de contatos do gmail) do gmail. Então eu clico neste botão:
    Adicionar conexão

  2. Uma página da Web aparece e mostra a página de login do Gmail, quando insiro minha conta e senha:
    Adicionar conexão

  3. O Gmail mostra uma página de consentimento onde clico em "Aceitar": Adicionar conexão

  4. Agora o LinkedIn pode acessar meus contatos no Gmail: Adicionar conexão

Abaixo está um fluxograma do exemplo acima:

Adicionar conexão

Etapa 1: o LinkedIn solicita um token ao Servidor de Autorização do Gmail.

Etapa 2: o servidor de autorização do Gmail autentica o proprietário do recurso e mostra ao usuário a página de consentimento. (o usuário precisa fazer login no Gmail se ainda não estiver conectado)

Etapa 3: o usuário concede a solicitação para o LinkedIn acessar os dados do Gmail.

Etapa 4: o servidor de autorização do Gmail responde com um token de acesso.

Etapa 5: o LinkedIn chama a API do Gmail com este token de acesso.

Etapa 6: o servidor de recursos do Gmail retornará seus contatos se o token de acesso for válido. (O token será verificado pelo servidor de recursos do Gmail)

Você pode obter mais detalhes sobre o OAuth aqui .

Owen Cao
fonte
Todas as suas imagens desapareceram. Alguma chance de carregá-los no stack.imgur?
ChrisF
1
Como isso pode estar correto? Esse processo não é iniciado pelo usuário sentado em frente ao navegador, não ao LinkedIn. Mas você tem isso como passo 3. É isso que eu não entendo.
24516 Matt
17
A explicação mais fácil. Obrigado, eu nunca vou comprar rosquinhas novamente
OverCoder
4º passo o linkedin retorna com um token de autorização. Isso deve ser fornecido na 5ª etapa, onde obteremos um token de acesso e um token de atualização que podem ser usados ​​ainda mais para recursos protegidos.
Amth3
@amesh Obrigado, você está certo, que é o fluxo de código de autorização, aqui, eu simplesmente declarou de forma simplificada para mostrar a idéia básica de OAuth 2.
Owen Cao
24

Figura 1, retirada do RFC6750 :

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+
8bitjunkie
fonte
13

É assim que o Oauth 2.0 funciona, bem explicado neste artigo

insira a descrição da imagem aqui

Suraj
fonte
Você pode descrever o OAUTH2 em termos de não usar o facebook ou de terceiros, mas se usar chave secreta e tokens TOTP com o aplicativo de telefone para proteger o aplicativo da web?
Al Grant
O Facebook é o servidor de autorização neste exemplo que emite o token de acesso a qualquer cliente para que eles possam acessar as APIs do Facebook. Se você deseja proteger suas APIs, precisa implementar seu próprio servidor de Autorização. Em seguida, você decide qual tipo de concessão você deseja usar para obter o token de acesso. me diga o que exatamente você quer? vai explicar.
Suraj
Eu estou olhando para configurar com segurança springboot. O cliente (telefone) e o webapp trocam segredo no registro - em seguida, use o google authenticator para gerar código baseado em tempo / segredo para inserir durante o login, além da senha.
Al Grant
meu último comentário o esclarece mais? Ver o meu perfil para informações do twitter
Al Grant
você pode obter o ID e o segredo do cliente no registro. Em seguida, telefone, faça uma solicitação de login com o ID do cliente no seu aplicativo da web (servidor de autorização). O aplicativo da Web valida o ID do cliente e envia o OTP para o telefone. O telefone faz outra solicitação com segredo do cliente para o webapp para trocar o OTP com o token de acesso. telefone, use este token de acesso para acessar os recursos protegidos no aplicativo da web. Eu acho que esse seria o fluxo Oauth2 para o cenário especificado. deixe-me saber se isso ajuda você.
Suraj
10

Esta é uma jóia:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Resumo muito breve:

OAuth define quatro funções:

  1. Proprietário do recurso
  2. Cliente
  3. Servidor de Recursos
  4. Servidor de Autorização

Você (Proprietário do recurso) possui um telefone celular. Você tem várias contas de e-mail diferentes, mas deseja todas as suas contas de e-mail em um aplicativo, para não precisar continuar trocando. Assim, seu GMail (Cliente) solicita acesso (via Servidor de Autorização do Yahoo) aos seus emails do Yahoo (Resource Server) para que você possa ler os dois emails no seu aplicativo GMail.

A razão pela qual o OAuth existe é porque não é seguro para o GMail armazenar seu nome de usuário e senha do Yahoo.

insira a descrição da imagem aqui

Belfield
fonte
8

A outra resposta é muito detalhada e aborda a maior parte das questões levantadas pelo OP.

Para elaborar e especificamente abordar a questão do OP de "Como o OAuth 2 se protege contra ataques de repetição usando o Token de Segurança?", Há duas proteções adicionais nas recomendações oficiais para a implementação do OAuth 2:

1) Os tokens normalmente terão um curto período de validade ( http://tools.ietf.org/html/rfc6819#section-5.1.5.3 ):

Um curto período de validade dos tokens é um meio de proteção contra as seguintes ameaças:

  • repetir ...

2) Quando o token é usado pelo Site A, a recomendação é que ele seja apresentado não como parâmetros de URL, mas no campo de cabeçalho da solicitação de autorização ( http://tools.ietf.org/html/rfc6750 ):

Os clientes devem fazer solicitações autenticadas com um token de portador usando o campo de cabeçalho de solicitação "Autorização" com o esquema de autorização HTTP "Portador". ...

O método "application / x-www-form-urlencoded" NÃO DEVE ser usado, exceto em contextos de aplicativos em que os navegadores participantes não tenham acesso ao campo de cabeçalho de solicitação "Autorização". ...

O parâmetro de consulta URI ... está incluído para documentar o uso atual; seu uso não é recomendado devido a suas deficiências de segurança

Vai
fonte
3

Aqui está talvez a explicação mais simples de como o OAuth2 funciona para todos os quatro tipos de concessão, ou seja, quatro fluxos diferentes nos quais o aplicativo pode adquirir o token de acesso.

Semelhança

Todos os fluxos do tipo de concessão têm 2 partes:

  • Obter token de acesso
  • Usar token de acesso

A segunda parte 'usar token de acesso' é a mesma para todos os fluxos

Diferença

A primeira parte do fluxo 'obter acesso token' para cada tipo de concessão varia.

No entanto, em geral, a parte 'obter acesso token' pode ser resumida em 5 etapas:

  1. Pré-registre seu aplicativo (cliente) no provedor OAuth, por exemplo, Twitter, etc. para obter o ID / segredo do cliente
  2. Crie um botão de login social com o ID do cliente e os escopos / permissões necessários em sua página para que, quando o usuário clicado for redirecionado ao provedor OAuth, para ser autenticado
  3. O provedor OAuth solicita que o usuário conceda permissão ao seu aplicativo (cliente)
  4. O provedor OAuth emite código
  5. O aplicativo (cliente) adquire o token de acesso

Aqui está um diagrama lado a lado comparando como cada fluxo de tipo de concessão é diferente com base nas 5 etapas.

Este diagrama é de https://blog.oauth.io/introduction-oauth2-flow-diagrams/

insira a descrição da imagem aqui

Cada um tem diferentes níveis de dificuldade de implementação, segurança e casos de uso. Dependendo de suas necessidades e situação, você terá que usar um deles. Qual usar?

Credencial do cliente : se seu aplicativo estiver servindo apenas um único usuário

Crendencial da senha do proprietário do recurso : deve ser usado apenas como último recurso, pois o usuário deve entregar suas credenciais ao aplicativo, o que significa que ele pode fazer tudo o que puder.

Código de autorização : a melhor maneira de obter autorização do usuário

Implícito : se seu aplicativo for móvel ou de página única

Há mais explicações sobre a escolha aqui: https://blog.oauth.io/choose-oauth2-flow-grant-types-for-app/

nethsix
fonte