Um 'if password == XXXXXXX' é suficiente para segurança mínima?

20

Se eu criar um login para um aplicativo que tenha riscos de segurança médios a baixos (em outras palavras, não é um aplicativo bancário ou algo assim), é aceitável verificar uma senha inserida pelo usuário dizendo apenas algo como:

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

Parece fácil ser eficaz, mas eu certamente não me importaria se isso fosse tudo o que era necessário. Uma verificação simples no nome de usuário / senha é suficiente?

Atualização: o projeto em particular é um serviço da Web, a verificação é inteiramente do servidor e não é de código aberto. O domínio muda como você lidaria com isso?

Morgan Herlocker
fonte
3
depende de onde vem o validPassword? se for codificado, você não poderá configurar / alterar a senha sem alterar o código. Se vier de um arquivo de configuração, estará visível para quem acessá-lo.
Alb
1
"é suficiente uma verificação no nome de usuário / senha" para fazer o que?
18711 Chris
3
@opinion: parece improvável que isso seja pior do que não ter um login. Forneça algum raciocínio para uma reivindicação tão forte.
Morgan Herlocker
1
Sua terminologia está incorreta; quando você compara uma senha, está verificando-a, sem garantir que ela seja válida. Por favor, dedique um tempo para entender a diferença.
billy.bob
1
Isso implica em armazenamento de senha em texto sem formatação, o que é irresponsável. Implica também alertar um usuário de que a senha estava incorreta, o que fornece informações importantes a um invasor em potencial. Você deve sempre ser ambíguo, ou seja, "Login ou senha incorretos".
Rein Henrichs

Respostas:

26

Não sem SSL

Isso não é seguro se a senha for enviada pela rede em texto sem formatação. Hashing da senha no lado do servidor também não é seguro se a senha for enviada pela rede em texto sem formatação.

Como a <input type="password"/>tag HTML envia seu conteúdo em texto sem formatação, isso será um problema, independentemente de como você armazena a senha no servidor, a menos que o site use SSL para transmitir a senha.

(A autenticação HTTP, que abre uma caixa de diálogo no navegador solicitando uma senha, pode ou não ser um texto não criptografado, dependendo de quais mecanismos de autenticação o servidor e o navegador têm em comum. Portanto, isso pode ser uma maneira de evitar isso sem usar SSL.)

Não se os administradores do site forem suspeitos

Agora, supondo que você esteja usando HTTPS para fazer o site, isso pode ser seguro se você confiar nos administradores do site (que podem ler senhas em texto sem formatação) e em outras pessoas que têm acesso à máquina para se comportarem corretamente. Agora, pode ser óbvio que eles podem fazer o que quiserem com seu site (uma vez que o administram), mas, se puderem ler a senha, também poderão usar os pares de login / senha roubados nos sites de outras pessoas.

Uma maneira de manter as senhas protegidas do administrador

Uma maneira segura de armazenar e verificar senhas é a seguinte:

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

Para a função hash, tente usar algo forte e algo que ainda não tenha boas tabelas de arco-íris. Você pode alterar o comprimento do sal, se necessário, contornar as tabelas do arco-íris.

Dependendo do ambiente em que você está, da variabilidade na latência da rede e se os nomes de usuário devem ser conhecidos publicamente, convém ter outro caminho de código computado hash('0000'+entered_password)se o usuário não existir, para impedir que invasores determinar quais nomes de usuário são válidos com base no tempo que leva para determinar se a senha está incorreta.

Ken Bloom
fonte
1
Bons conselhos :) Em relação ao SSL, fomos solicitados a projetar algo que funcionasse em estado selvagem e simplesmente usamos criptografia assimétrica para codificar a senha (requer Javascript) e depois decodificá-la no servidor. O salt + hash ocorre normalmente. Além disso, como a chave pública é enviada com a página da Web, ela pode mudar arbitrariamente com frequência.
Matthieu M.
1
@ Matthieu M .: Quando alguém pode falsificar sua página da Web, ele também pode alterar a chave pública lá para uma onde ele mesmo conheça a chave privada correspondente. Portanto, sua ideia ajuda apenas contra ataques de leitura passivos, não contra o homem do meio.
Pa Elo Ebermann
@Paulo: sim, eu concordo que o SSL não é apenas sobre criptografia, mas também sobre certificado, infelizmente eu não ligo aqui, e quando as pessoas dizem que querem usar a página da Web com uma http://conexão regular ... é frustrante: /
Matthieu M.
@ Mattthieu: Isso significa que você está enviando public_key como parte da página pública da web, computando encrypt(entered_password, public_key)no cliente e enviando esse resultado ao servidor, que executa does_password_match?(user, decrypt(encrypted_password, private_key))?
Ken Bloom
@ Ken: mais ou menos, você acertou a criptografia. Para combinar a senha é mais does_password_match(user, salt, decrypt(encrypted, key)), com o sal dependendo do usuário. Como eu disse, a questão óbvia é a falta de proteção do homem do meio.
Matthieu M.
52

Isso sugere que você mantenha as senhas em texto aberto, o que é um não-não, mesmo em cenários de baixa segurança.

Você deveria ter:

if(hash(enteredPassword) == storedHash)

Você pode usar hash simples, como por exemplo MD5

vartec
fonte
22
+1 por hash da senha. Mas pelo menos eu adicionaria um pouco de sal. Caso contrário, como os usuários reutilizarão nomes de usuário e senhas entre sistemas, violar seu aplicativo de baixa segurança pode permitir que um invasor viole um aplicativo de segurança muito mais alto. O recente hack da HBGary, por exemplo, conseguiu comprometer o sistema CMS executando o site e transformá-lo em acesso root aos servidores em parte porque o sistema CMS de baixa segurança não estava adicionando sal aos hashes arstechnica.com/tech-policy/ news / 2011/02 /…
Justin Cave
1
Concordo ... considere o seguinte .. "strings JavaFile.class | grep -i password"
Bill
Qual é o problema de ter a senha em texto sem formatação se elas forem usadas apenas uma vez?
10
@ Tim, porque os usuários não usarão a senha apenas uma vez. Os estudos mostram consistentemente que os usuários reutilizam senhas várias vezes (por exemplo, theregister.co.uk/2011/02/10/password_re_use_study ), não importa quantas vezes eles sejam instruídos a não usar.
1811 Scott Scott
3
@ Tim: além disso, basta abrir seu exe, dll, etc, em um editor de texto, e você provavelmente verá sua senha ali.
Gus Cavalcanti
14

Concordo com aqueles que sugerem o hash, mas também há uma roda que você está reinventando aqui. Dependendo da plataforma, é provável que você encontre uma ferramenta de gerenciamento de funções / usuários que cubra todo o material de gerenciamento de usuários com segurança e sem a necessidade de muita intervenção de sua parte.

glenatron
fonte
Acabei de descobrir os provedores de associação do ASP.Net, mas estava olhando para eles pensando "quantas vezes perdi meu tempo implementando algo assim?"
glenatron
8

A segurança é um assunto muito delicado, principalmente porque é preciso haver um equilíbrio entre incomodar seus usuários e garantir que suas informações estejam seguras. Normalmente, a fórmula para quanta segurança você precisa é uma função da importância dos dados. Em resumo:

isSecuritySufficient = effortToBreak > rewardForBreaking

Um mal-entendido comum sobre pessoas que fazem coisas ruins é o que elas buscam. A maioria deles pretende destruir a confiança . Você sempre deve fazer tudo o que puder para proteger a confiança de seus usuários. Parte disso é fazer sua devida diligência para garantir que a identidade deles seja segura. Eles podem se importar menos com os dados que armazenam, mas se preocupam com sua identidade - mesmo no limite mais baixo de segurança.

Há várias opções de baixo custo (para implementar e impactar o usuário) disponíveis. Um deles é o hash da senha no mínimo. Qualquer serviço que armazene algo tão sensível quanto uma senha em texto simples merece o constrangimento de ser invadido.

Princípios gerais para proteção de senha

  • Nunca armazene senhas em texto simples
  • Hash usando uma função de hash seguro como SHA-1 ou mesmo SHA-512 (até o MD5 é muito fácil de encontrar um hash correspondente)
  • Use um valor de sal de aplicativo. O salt é bytes aleatórios adicionados a uma senha para dificultar a adivinhação. O sal deve ser gerado no tempo de execução e usando informações sobre a máquina como um valor inicial, em vez de armazenado e referenciado de qualquer forma.
  • Use um valor de sal específico do usuário. Use isso em conjunto com o seu sal de aplicação.
  • Criptografe todas as solicitações de autenticação que passam por uma rede. Isso significa usar SSL para aplicativos da web.

Como você usaria SSL para a autenticação, no mínimo você deseja criptografar todas as páginas que lidam com a conta do usuário. Isso permite que o máximo possível da identidade de um usuário seja protegido.

Uma observação sobre o gerenciamento de senhas : os usuários esquecem suas senhas de tempos em tempos. A pior coisa que você pode fazer é enviar a senha deles por e-mail. Se você implementar os princípios descritos acima, não poderá fazer isso de qualquer maneira. É muito melhor fornecer uma maneira de redefinir sua senha usando um link enviado para o endereço de e-mail registrado. Esse link de redefinição terá um código de uso único para garantir que a pessoa que acessa a página seja ela.

Berin Loritsch
fonte
1
No começo, fiquei realmente impressionado com a idéia de aplicação salt + user salt, mas quanto mais penso nisso, menos convencido estou. Se você utilizou, digamos, 4 caracteres de sal de aplicativo e 4 de sal de usuário, a diferença entre esse e 8 caracteres de sal de usuário é apenas que metade do sal seria idêntica para cada usuário. Parece que seria mais seguro aumentar apenas o tamanho do sal do usuário, em vez de ter sal de aplicação. Além disso, se o salt do aplicativo for baseado no hardware, você não poderá atualizar ou alterar o hardware sem invalidar todas as senhas.
David Conrad
O problema é que o salt do usuário é incluído na linha do banco de dados com a senha do usuário. Se uma pessoa má sabe para que serve um sal (e o faz) e o vê no banco de dados, então sabe como quebrá-lo completamente. A inclusão de uma parte no aplicativo que é calculada (da mesma maneira que sempre que você lembra) em vez de armazenada, torna muito mais difícil decifrar as tabelas de usuários. É claro que você pode dar um passo adiante e fazer 1 parte de sal aleatório puro e 1 parte de sal calculado, sendo ambos específicos do usuário.
Berin Loritsch 14/03
Ah, entendo, mantenha parte do sal fora do banco de dados. Isso faz sentido. Obrigado.
David Conrad
Não vejo problema em armazenar o sal por linha, desde que seja único por linha. Aqui está um hash: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91" (SHA256), eis o sal: "671254bdf7944f8fa88e6c9913b948ee". Pense que você pode obter a senha? Não existe uma tabela de arco-íris para esse sal (mesmo que você receba sal), você está preso forçando-o com força bruta.
22912 Bryan Boettcher
3

Tudo bem, a menos que a senha seja usada para qualquer outra coisa. Ainda existe o risco de o usuário decidir que pode reutilizar a senha, por isso seria ainda melhor com:

if(hash(enteredPassword) == hashOfValidPassword)

Se é para você ou para alguém que sabe que a senha está armazenada em texto sem formatação, tudo bem.


fonte
1
Como no comentário de Justin Cave à resposta da vartec, use sal, então if (hash (enteredPassword + salt) == hashOfValidSaltedPassword)- e observe que +provavelmente é concatenação, não adição. Isso realmente dificulta o uso de tabelas arco-íris, que são tabelas de hashes de senhas prováveis.
David Thornley
se tudo o que você está procurando é um hash, eles não podem apenas executar um loop de possíveis strings até que um gere o mesmo hash que o hash armazenado? Afinal, existem muitas strings que podem corresponder ao mesmo hash.
Morgan Herlocker
@Prof Plum: É muito difícil encontrar colisões se o algoritmo de hash for bom. Essa é a base da criptografia moderna: elas são essencialmente funções unidirecionais.
3

O código fonte está disponível? Mesmo se não, tenho certeza de que a senha pode ser encontrada nas instruções da máquina, caso o binário esteja disponível. Eu recomendaria fazer uma soma de verificação e compará-la.

Nunca negligencie a segurança, mesmo que não seja muito importante na sua opinião.

Anto
fonte
2
Sim, má ideia se for um projeto de código aberto :)
-1 - Se você acha que ter a fonte faz diferença, não sabe nada sobre segurança.
mattnz
1

Absolutamente não. Leia isso e descreve como os hackers invadiram um site de segurança. Você planeja ter você como o elo mais fraco da cadeia.

Dave
fonte
0

Foi observado em algumas respostas que você não deve armazenar a senha em si, mas um hash - e você deve usar SSL.

Você pode dizer, qual é o grande problema? Se meu aplicativo for invadido, isso é de pouca preocupação. Bem, é um padrão bastante comum para os usuários reutilizarem a mesma senha em todos os sites. Se um hacker invadisse seu site e ganhasse acesso às senhas dos usuários, o hacker poderia se passar por muitos desses usuários em outros sites de maior importância para esses usuários. Portanto, invadir seu site pode ser o primeiro passo para um hacker obter acesso a informações bancárias para os usuários.

E apenas o hash da senha não é suficiente. Você precisa misturá-lo com sal. Os hackers têm tabelas de pesquisa inversa de hash, portanto, para um determinado hash, eles podem encontrar uma senha correspondente.

Se você optar por não implementar esses recursos, informe os usuários dessa falta de segurança, incentivando-os a não usar a mesma senha que eles usam em outros lugares.

Pete
fonte
-2

Contanto que este seja o lado do servidor .. Então sim.

Se você quiser um pouco mais de segurança, vá para https e criptografe \ hash a senha no banco de dados.

Idiotas
fonte
3
Por que supor que este é um aplicativo da web?
18711 Chris
Bom ponto! Eu apenas fiz.
Idiotas
4
-1, mesmo que seja do lado do servidor, isso ainda não está ok.
GSto