Qual é a melhor maneira de implementar "lembre-se de mim" em um site? [fechadas]

510

Quero que meu site tenha uma caixa de seleção na qual os usuários possam clicar para que não precisem fazer login sempre que visitarem meu site. Eu sei que precisarei armazenar um cookie no computador deles para implementar isso, mas o que deve estar contido nesse cookie?

Além disso, há erros comuns a serem observados para impedir que esse cookie apresente uma vulnerabilidade de segurança, o que poderia ser evitado enquanto a funcionalidade 'lembre-se de mim' ainda é exibida?

Vort3x
fonte
5
Verifique stackoverflow.com/questions/549/… (parte II da resposta superior)
Frosty Z
se você estiver usando o ASP.NET, confira codeproject.com/Articles/779844/Remember-Me
Believe2014
1
Há algumas informações muito úteis sobre a Segurança SE ~ security.stackexchange.com/questions/19676/...
b1nary.atr0phy
A resposta atualmente aceita por splattne é excessivamente complexa. Crie um token de +16 bytes a partir de uma fonte aleatória, faça o hash e salve o ID da conta do hash + no banco de dados. Em seguida, envie o token para o usuário (codificado em base64) em um cookie HTTPS + httpOnly (para que o Javascript não possa acessá-lo / roubá-lo). Dessa forma, ninguém pode adivinhar o token ou desconectar as pessoas com palpites inválidos; mesmo que seu banco de dados seja invadido, ninguém poderá usar os tokens no banco de dados (eles estão com hash). Portanto, apenas o cliente original (ou alguém que rouba o token da loja do navegador de alguma forma) pode usá-lo.
Xeoncross 02/01

Respostas:

536

Prática recomendada aprimorada de cookie de login persistente

Você pode usar esta estratégia descrita aqui como melhor prática (2006) ou uma estratégia atualizada descrita aqui (2015):

  1. Quando o usuário efetua login com o recurso Remember Me marcado, um cookie de login é emitido além do cookie de gerenciamento de sessões padrão.
  2. O cookie de login contém um identificador de série e um token . A série e o token são números aleatórios indiscutíveis de um espaço adequadamente grande. Ambos são armazenados juntos em uma tabela de banco de dados, o token é hash (sha256 é bom).
  3. Quando um usuário não conectado acessa o site e apresenta um cookie de login, o identificador de série é pesquisado no banco de dados .
    1. Se o identificador de série estiver presente e o hash do token corresponder ao hash desse identificador de série, o usuário será considerado autenticado . Um novo token é gerado, um novo hash para o token é armazenado no registro antigo e um novo cookie de login é emitido para o usuário (não há problema em reutilizar o identificador de série ).
    2. Se a série estiver presente, mas o token não corresponder, será assumido um roubo . O usuário recebe um aviso com palavras fortes e todas as sessões lembradas do usuário são excluídas.
    3. Se o nome de usuário e a série não estiverem presentes, o cookie de login será ignorado .

Essa abordagem fornece defesa em profundidade. Se alguém conseguir vazar a tabela do banco de dados, isso não dará a um invasor uma porta aberta para se passar por usuários.

splattne
fonte
20
veja também: stackoverflow.com/questions/549/… você NÃO deve ler a versão 'aprimorada'
Jacco
8
O problema é que você expõe o nome de usuário no cookie, embora seja isso que o Gmail faz. Por que você precisa de um ID de série e um token? Um token maior não seria bom?
21411 Dan Rosenstark
10
Além disso, em relação a esse modelo, o que impedir um invasor de roubar e depois colocar o cookie no computador e excluir o cookie do computador invadido. O computador dele seria autenticado e atualizado conforme necessário, sem o computador invadido? A única mudança seria que o usuário de computadores invadidos teria que fazer login novamente e definir "lembre-se de mim". Se o usuário hackeado reconhece ou não isso seria incerto.
24
@HiroProtagonist O identificador de série é para evitar um ataque de negação de serviço. Sem ele, eu poderia escrever rapidamente um script atingindo seu site com todo nome de usuário e um token inválido, desconectando todos os usuários do site.
Chris Moschini
6
Esta solução está ERRADA, não lida com a simultaneidade: se duas solicitações de autenticação Lembre-me chegarem ao mesmo tempo, com o mesmo cookie Lembre-me, a primeira obtém êxito e altera o token, a segunda causa uma autenticação malsucedida e um alarme falso (porque o token já foi alterado pela primeira solicitação). (Esta situação pode acontecer quando o navegador é iniciado, eo site é restaurada em duas abas do navegador.)
Slobo
9

Eu armazenaria um ID do usuário e um token. Quando o usuário voltar ao site, compare essas duas informações com algo persistente como uma entrada de banco de dados.

Quanto à segurança, apenas não coloque nada que permita que alguém modifique o cookie para obter benefícios extras. Por exemplo, não armazene seus grupos de usuários ou sua senha. Qualquer coisa que possa ser modificada que possa contornar sua segurança não deve ser armazenada no cookie.

dragonmantank
fonte
8

Armazene seu UserId e um RememberMeToken. Quando eles se conectam com o recurso Lembre-me marcado, gera um novo RememberMeToken (que invalida todas as outras máquinas marcadas como Lembre-se de mim).

Quando eles retornarem, procure-os pelo token de lembrar-me e verifique se o UserId corresponde.

jonnii
fonte
Isso pode ser brutal forçado em segundos. Vou definir meu user_id como 1 e força bruta todos os tokens. Isso me dará acesso em segundos
Um amigo
4

Investigando sessões persistentes, descobri que simplesmente não vale o risco à segurança. Use-o se for absolutamente necessário, mas você deve considerar essa sessão apenas fracamente autenticada e forçar um novo login para qualquer coisa que possa ter valor para um invasor.

O motivo é claro, é que seus cookies que contêm sua sessão persistente são tão facilmente roubados.

4 maneiras de roubar seus cookies (de um comentário de Jens Roland na página com @splattnebase em sua resposta):

  1. Interceptando-o em uma linha não segura (detecção de pacotes / seqüestro de sessão)
  2. Acessando diretamente o navegador do usuário (via malware ou acesso físico à caixa)
  3. Lendo-o no banco de dados do servidor (provavelmente SQL Injection, mas poderia ser qualquer coisa)
  4. Por um hack de XSS (ou uma exploração similar do lado do cliente)
Jarl
fonte
104
1. O HTTPS foi projetado para evitar isso. 2. Mantenha-se conectado não é o problema de segurança aqui, você tem problemas maiores. 3. Igual ao 2. 4. Isso pode ser evitado pela política de controle de acesso e pelo bom saneamento de insumos; se você não seguir essas etapas, novamente terá problemas maiores do que permanecer logado.
Chris Moschini