Skip to content

Latest commit

 

History

History
275 lines (218 loc) · 9.45 KB

01-intro.md

File metadata and controls

275 lines (218 loc) · 9.45 KB

Introdução

Visão geral

  • Recapitular: Session Identifiers
  • Cookies, da maneira correta
  • Introdução a JWT
  • Access Tokens e Refresh Tokens
  • Armazenando JWTs no browser
  • Angular especificidades

Recapitular: Session Identifiers

Identificadores de sessão, esse é uma maneira prática e simples para gerenciar uma sessão para um usuário que consiste básicamente em três passos:

  • Verificar usuário e senha
  • Criar uma session ID e associar ao usuário
  • Guardar a session ID em um cookie
  • a imagem abaixo detalha como isso acontece:

    podemos ver que o usuário faz login e quando isso acontece é enviando o login e senha via POST estando tudo certo o servidor retorna um http statusCode 200 e seta um ID para a sessão armazena esse session ID em um cookie e quando o usuário fizer uma requisição para profile por exemplo é feito um get nesse cookie e nesse momento ocorre uma verificação se o session ID for igual ao que foi enviando pelo servidor então e retornado um 200 e para cada requisição tudo ocorre asim.

    Preocupação com session ID

    • eles não tem nenhum significado são códigos gerados aleatoreamente
    • aumenta a carga ao banco de dados, é feita uma pesquisa pelo session ID em cada requisição
    • precisam ser protegidos para evitar ataques a sessão

    Cookies, da maneira correta

    Cookies podem ser facilmente comprometidos:

    • Man-in-the-middle (MITM)
    • Cross-Site Scripting (XSS)
    • Cross-Site Request Forgery (CSRF)

    Man-in-the-middle (MITM)

    Alguém pode ouvir a conversa entre o browser e o servidor e interceptar e roubar o cookie durante essa 'conversa'

    Solução:

  • Usar HTTPS/TLS em todos os locais onde um cookie irá transitar
  • Set secure flag no cookie
  • Cross-Site Scripting (XSS)

    Esse é um problema real, e ocorre quando alguém roda um script mal intencionado dentro do browser direcionado para o dominio a ser atacado e pode ser usado para roubar cookies.

    aqui temos um exemplo isso EXEMPLO. podemos ver no exemplo que é executado um código malicioso no browser e com isso o atacante tem acesso a todos os nossos cookies.

    Solução:

  • Server Side: usar bibliotecas conhecidas e confiáveis para garantir que o HTML dinâmico não contém código executável. que não foi gerado por nós é claro.
  • Client Side: verificar inputs em forms enviandos pelo usuário existem frameworks que podem fazer isso por nós, mas é sempre bom ver a documentação.
  • Setar o atributo HttpOnly para authenticação dos cookies. Com HttpOnly os cookies não são acessíveis pelo javascript environment.
  • links de exemplo: https://www.owasp.org/index.php/XSS
    https://www.google.com/about/appsecurity/learning/xss/

    Cross-Site Request Forgery (CSRF)

    Explora o fato de tags HTML não seguir a mesma política de origem ao fazer solicitações GET.

    exemplo: um atacante coloca uma imagem com conteúdo malicioso dentro de uma pagina WEB que seus usuários visitam.

    <img src="https://trustyapp.com/transferMoney?to=BadGuy&amount=10000"/>
    

    o que irá acontecer aqui é:

  • o browser irá enviar cookies para trustapp.com.
  • o servidor enviar um cookie confiável e assume que foi uma ação do usuário.
  • transfere o dinheiro.
  • Solução:

  • Sincronizar token (para aplicações form-based)
  • Double-submit cookie ( para aplicações modernas)
  • Double-submit cookie

  • cliente tem dois cookies, o um é session ID e o segundo é um valor random.
  • Client envia de volta um valor random no header, desencadeando o same-origin-policy.
  • a imagem abaixo detalha como isso acontece:

    e o servidor agora sabe tratar e rejeitar a ação maliciosa.

    a imagem abaixo detalha como isso acontece:

    para saber mais: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
    https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

    Introdução a JWT

    Definição

  • Authenticação: é quando provamos quem somos.
  • Authorização: é quando garantimos que temos acesso algum resource.
  • Tokens: são usados para persistir a authenticação e para pegar ( get ) a authorização.
  • JWT: é um formato de token.
  • JSON web tokens (JWT)

    um JWT parece com uma string sem sentido algo do tipo

    eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJ
    pc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQo
    gImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnV
    lfQ.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEj
    Xk
    

    mas ele não é 'sem sentido', o JWT consiste em uma estrutura com três partes encodadas em Base64-URL:

    e esse mesmo JWT decodificado fica dessa forma:

    o body do JWT é a parte mais importante e está dividida da seguinte forma:

    {
      "iss":"http://trustapp.com/", <---- quem emitiu o token.
      "exp":"1300819380", <---- quando vai expirar.
      "sub":"users/258594", <---- quem representa ( usuário ).
      "scope":"self api/buy", <--- o que pode fazer.
    }

    Enviando e verificando JWTs

    Enviando JWTs:

  • User tem que apresentar credenciais para ter um token (password , api keys).
  • Tokens são enviados pelo servidor e assinados com uma chave secreta que é privada.
  • O client guarda o token e o usa para authenticar os requests.
  • Verificando JWTs:

  • Deve checar a assinatura e tempo para expiração ( stateless authentication ).
  • Token declara o scopo, tomar decisões de autorização localmente.
  • mas como revogar stateless authentication.
  • OAuth2 + JWT ( Access & Refresh Tokens )

    Access & Refresh tokens:

  • O cliente tem acesso e atualiza o token.
  • Access token expira antes da atualização do token.
  • Refresh token é usado para pegar mais access tokens.
  • Access tokens são confiáveis por assinatura.
  • Refresh tokens são checados para revogação.
  • Lhe da o controle baseado no tempo de troca: stateless confiável vs Database lookup.

    Exemplos:

    • Super-seguro ( se deseja forçar o usuário a sair rapido: )
      • Access token TTL = 1 minuto
      • Refresh token TTL = 30 minutos
    • Mobile/social app ( usuário deve ficar sempre logado )
      • Access token TTL = 1 hora
      • Refresh token TTL == 4 anos
    Armazenando e transmitindo JWTs ( no browser )

    preocupações:

    • Local storage não é seguro ( XSS vulnerabilidade)
    • Cookies são segures, com HttpOnly, Secure Flags e CSRF prevenção.
    • Usando o header Authorização fica legal mas não é realmente necessário.
    • Cross-domain request são sempre um inferno :D

    Lógica de authenticação usnado cookies:

    • Existe um token e acesso? ele é valido? ( assinatura e expiração)?
      • Sim? libera o request!
      • Não? tente pegar um novo access token, usando o refresh token
        • Isso funcionou?
          • Sim? libera o request e manda o novo acess token no response como cookie.
          • Não? Rejeita o request e deleta o refresh token cookie.

    Entãooo... AngularJS?

    JWT com angularJS

  • Como eu vou saber se um usuário está logado?
  • Como eu vou saber se um usuário tem acesso a view?
  • Como eu vou saber se um usuário está com acesso removido?
  • O usuário está logado?

  • Cookies não pode lhe dizer isso, se estivermos usando HttpOnly
  • Vamos fazer um request para '/me' route com solicitação do token authentication
  • O route retorna o objeto do usuário
  • Use uma promisse para retornar esse objeto
  • exemplo: ````js angular.module('myapp') .config(function($stateProvider) { $stateProvider .state('home', { url:'/', templateUrl: 'views/home.html', resolve: { user: function($auth) { return $auth.getUser(); } } }) }) ````
  • UI Router: usa $stateChangeError para enviar qualquer erro da promisse, e direcionar para a view login.
  • ngRoute: $routeChangeError
    • manter $rootScope.user
      • null = nós não sabemos quem é
      • fakse = não esta logado
      • { } = nos temos um usuário data
  • Transmissão $authenticated é o evento disparado quando o usuário é conhecido.
  • Verificar o acesso do usuário para a view exemplo:

    $stateProvider
      .state('home', {
        url:'/',
        templateUrl:'views/home.html',
        resolve: {
          user: function($auth) {
            return $auth.getUser()
              .then(function(user) {
                // pode ter acesso a view?
                return true/false;
                })
          }
        }
        })

    Se o acesso foi removido?

  • Se recebermos um 401 como statusCode a transmissão do evento ocorre em $unauthenticated event
  • Redireciona para login view.