2013/11/22

Como não guardar as Passwords


Eu sei que já abordei o assunto da segurança das passwords - e do hashing e do salting - mas considerando que continuamos a ver sites a cometerem enormes erros, como guardarem passwords em "plain text", ou password encriptadas (a Adobe!) penso que será bom voltar a relembrar como não se devem guardar as passwords.



Mesmo para quem não tiver grandes conhecimentos técnicos de programação, penso que a coisa pode ser facilmente compreendida. Quando um site permite o registo de utilizadores, é óbvio que esses dados têm que ficar guardados nalgum lado, para que um utilizador possa ser reconhecido quando lá regressar no futuro. Esses dados são guardados nas chamadas "bases de dados", que são aquilo que os hackers tanto gostam, para ter acesso a essa informação...

Então nessas bases de dados são criados registos contendo coisas como o nome do utilizador, o seu email, idade, e - a parte que nos interessa - a sua password.

Ora por aqui se pode ver que se lá colocarmos a password tal como ela foi introduzida pelo utilizador (o tal "plain text") qualquer pessoa que tenha acesso à base de dados poderá ver imediatamente a password de todos os utilizadores registados. E considerando que grande parte deles poderá utilizar a mesma password para múltiplos sites/serviços, isso torna-se num acto "criminoso" de falta de segurança que poderá colocar em risco toda a vida digital dos utilizadores que confiaram neste site para manter a sua password em segurança.

Portanto... como se pode manter a password em segurança?


Uma das opções que muitos considerariam seria encriptá-las (como no caso da Adobe). Assim, quem olhar para a base de dados não conseguirá perceber o que lá está. Mas... o problema é que a encriptação é um meio reversível. Quem conhecer o algortimo e chave utilizada poderá descodificar os dados encriptados - e se um hacker conseguiu aceder à base de dados, é bem provável que também tenha conseguido aceder ao código fonte do site, incluindo o sistema de descodificação.

Em qualquer um destes casos, a password não está em segurança, e isto é algo que qualquer utilizador poderá facilmente verificar fazendo uma "recuperação de password" após o seu registo num novo site (de preferência com uma password "descartável"). Se o site vos enviar um email a dizer: "a sua password é esta" - então fujam a sete pés e nem pensem em lá colocar uma password que usem noutros sites! (Aliás, nunca o deverão fazer, como regra básica de segurança.)


Mas então.. se não podemos guardar a password em texto normal, nem encriptada... o que nos resta?

O "hashing" é um sistema que permite criar um código a partir de qualquer sequência de dados. E a sua particularidade é que nos dá números estatisticamente únicos para toda e qualquer sequência diferente. Por exemplo: a sequência "AAA" poderá dar algo como "606ec6e9bd8a8ff2ad14e5fade3f264471e82251", mas qualquer pequena variação, como "AAB" dá algo completamente diferente: "bb672406219a6983eb909814cdefa3c0addca3ad". E isto tanto se pode aplicar a uma sequência de três letras como a um livro inteiro com centenas de páginas - com o resultado a ser sempre diferente, mesmo que mudem uma só vírgula.

O ponto importante das hashes é que é impossível inverter o processo (ao contrário do que acontece com a encriptação). Ou seja, a partir do momento em que têm uma hash, é "impossível" saberem qual a sequência que lhe deu origem. Se eu vos der a hash "3ef3b95aa1e461b9294f7650e897ecaea7a61e49", ninguém me poderá dizer que ela foi gerada a partir das obras completas de William Shakespeare, por exemplo.

É algo ideal para passwords, pois nós não queremos nem precisamos guardar a password original (que poderia ser roubada por hackers). Precisamos apenas comparar se a hash da password que o utilizador introduzir quando faz login no site bate certo com a hash que foi guardada quando ele se registou no site. Como as probabilidades de duas sequências/passwords diferentes darem a mesma hash, ficamos com o assunto arrumado. Certo?

Infelizmente nem por isso...

O problema é que os algoritmos de hashes mais comuns são bem conhecidos e já existem tabelas pré-calculadas das hashes das passwords de milhões de passwords já apanhadas. Para além disso, com sistemas especializados com vários GPUs a trabalhar em paralelo, é possível testarem-se muitos milhões de hashes por segundo, o que possibilita ataques "brute force", onde um programa vai testando todas as variações possíveis de passwords (e com algoritmos que aplicam variações populares, como trocar a letra E por 3, e outras coisas do género).

O que nos leva ao último detalhe que pode fazer toda a diferença para manter as passwords em segurança, do lado dos servidores: o "salting".

O salting é uma técnica simples, mas eficaz, que dificulta enormemente o trabalho dos hackers. Em vez de simplesmente calcular a hash de uma password (dando um resultado que já poderá estar no "registo" dos hackers), é adicionado uma segunda sequência aleatória a cada password - e diferente para cada utilizador. Este "salt" pode ficar guardado de forma perfeitamente visível na base de dados, pois não irá ajudar em nada um hacker que lhe consiga ter acesso.

É que assim, o ataque de verificação de passwords que poderia ser aplicado de rajada a todas as passwords tem que ser aplicada password a password, e o hacker tem que testar todas as combinações possíveis para cada salt de cada utilizador. Se a base de dados tiver 100 mil utilizadores, isto faz com que o ataque seja 100 mil vezes mais trabalhoso.


Mas, se estiverem a conceber um site de raiz, a minha recomendação é passarem completamente ao lado deste assunto. Guardem apenas o email do utilizador, e quando este fizer login enviem-lhe um email com um url contendo um token de acesso temporário, que ele poderá clicar para ter acesso ao site. Assim, a segurança passa a ser algo que fica a cargo do serviço de email do utilizador, e vocês podem dormir descansados por não terem qualquer responsabilidade em manter as suas passwords em segurança! :)

6 comentários:

  1. Ou seja, se hackarem a conta de mail... hackam todos os sites.

    Para isso prefiro Mail+HOTP?

    ResponderEliminar
    Respostas
    1. Rui, considerando que se te hackarem a conta já o fazem usando a recuperação de password em todos os sites em que te tiveres registado com esse email... Não me parece que seja problemático. Além do mais, podes investir em segurança reforçada no email (password segura + 2 step validation) para minimizar o risco.

      Eliminar
    2. Sim... mas se pedirem a anterior ou uma pergunta ... já aumenta a segurança.

      À uns anos vi um post no Reddit sobre um método BÁSICO. Julgo, que basicamente usavam login, email, pergunta todos cifrados. Para saberesum deles precisavas dos outros 2 mais a password/resposta.
      Infelizmente perdi o link.

      Eliminar
  2. Por tantas vezes falarem neste assunto, acabei por me dedicar um dia a mudar a maioria das passwords dos meus registos online. Defini uma regra que me permitisse usar passwords diferentes para todos os sites, mas esbarrei nas regras e limitações impostas pelos próprios sites. Acho ridículo que nos imponham caracteres obrigatórios, proibidos e comprimentos fixos de password.

    Outra coisa que me tenho dedicado é a contactar os webmasters dos sites quando verifico que não cumprem as regras de segurança que vocês aqui mencionam. Ainda não houve um que admitisse o erro.

    O mais bizarro que encontrei foi o do Portal do Utente que limita as passwords a 10 caracteres sem avisar que foi ultrapassado o numero máximo de caracteres. Posteriormente, quando tentas usar a password completa no login ficas à porta.

    Na minha opinião já era tempo de se definir uma norma que obrigasse os sites a permitir qualquer tipo de password.

    ResponderEliminar
  3. Eu costumo fazer o seguinte: substituo todos os caracteres (com uma tabela de correspondência) e em seguida aplico uma hash.
    A minha técnica de "encriptação" pode não ser a melhor, mas pelo menos dificulta um pouco as coisas.

    ResponderEliminar