• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Bjecas

Os cookies são sempre inseguros?

38 mensagens neste tópico

Estive a "brincar" com um script de login que encontrei na net, e pelo que pude perceber até está bem conseguido em termos de segurança. Excepto num pormenor... O script tem uma função "remember me?", que faz com que um código aleatório seja gerado e guardado na base de dados e também num cookie (com "serialize(username, código)" ).

Em cada página do site é verificada a variável $_SESSION['logged_in']. No caso de não estar definida, é procurado o cookie e depois de unseriaze(), é validado na base de dados contra o username e código aleatório gerado anteriormente. Ora, isto é quase igual a ter o username e password escarrapachadas no cookie! Se ele for interceptado, *poof*

Adicionei uma verificação de IP, ao guardar $_SERVER['REMOTE_ADDR'] na base de dados ao mesmo tempo que o código aleatório. Este valor é depois comparado com o IP actual quando o cookie é validado (o que acontece quando o cookie está presente e $_SESSION['logged_in'] não está definida).

Embora isto possa tornar a funcionalidade "remember me?" quase inoperante para quem tem IPs dinâmicos que mudem em intervalos de tempo curtos, pelo menos impede que alguém se faça passar por esse utilizador se não possuir o mesmo IP.

Mas isto implica que pessoas que apresentem IPs públicos iguais (por exemplo numa mesma sub-rede local) podem na mesma interceptar esses cookies e fazer-se passar pelo utilizador por possuirem o mesmo IP...

Por favor avisem-me se até aqui dei alguma bacorada  :D

Ora bem, a questão é se há alguma coisa que possa fazer (algo que possa meter no cookie, ou alguma verificação adicional) para resolver este problema de segurança? Não estou mesmo a ver uma alternativa...:cheesygrin:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Epa...é complicado. Talvez se colocares no cookie o username + password + ip. ou id + password + ip, fique muito bem seguro, porque a pessoa teria de ao logar introduzir tudo (a password de que falei estaria em hash claro) e só assim ele teria o ip...mas parece que é complicado proteger os cookies assim...

EDIT: Já sei! Se meteres um hash gerado autmoticamente quando a pessoa faz o login baseado no ip dela e na hora que é alterado a cada login!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Também podes sempre adicionar a limitação a um domínio específico... sempre fica mais seguro :cheesygrin:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Epa, é coisa que não uso muito, mas se fosse eu gerava um hash e guardava-o numa base de dados no servidor juntamente com o id do utilizador, data do ultimo login e mais alguma info que precises. Depois esse hash era tudo o que enviava para o cookie.

Quando o utilizador reentrasse procurava se o hash dele era valido ou nao, se existisse na tabela então estava autenticado.

Não estou a ver grande perigo nisto,o maior perigo é mesmo a possibilidade de alguem aceder ao mesmo computador de um qualquer utilizador e roubar-lhe a conta. Isto é um problema de segurança bem maior do que o que referiste e não está relacionado com encriptações, snifs de pacotes, nem nada parecido.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

EDIT: Já sei! Se meteres um hash gerado autmoticamente quando a pessoa faz o login baseado no ip dela e na hora que é alterado a cada login!

Se alguém apanhar o cookie não adianta, porque fica a saber a hash...

Também podes sempre adicionar a limitação a um domínio específico... sempre fica mais seguro :cheesygrin:

Estás a dizer limitar o cookie a um domínio específico? Nesse caso o problema talvez não fosse tão grave, mas mesmo assim a pessoa tinha que fazer login de novo para aceder às outras áreas.

...se fosse eu gerava um hash e guardava-o numa base de dados no servidor juntamente com o id do utilizador, data do ultimo login e mais alguma info que precises. Depois esse hash era tudo o que enviava para o cookie.

Quando o utilizador reentrasse procurava se o hash dele era valido ou nao, se existisse na tabela então estava autenticado.

Isso é mais ou menos o que tenho agora, e tem o problema de alguém apanhar o cookie e ficar a saber a hash, passando a poder imitar o utilizador legítimo...

Não estou a ver grande perigo nisto,o maior perigo é mesmo a possibilidade de alguem aceder ao mesmo computador de um qualquer utilizador e roubar-lhe a conta. Isto é um problema de segurança bem maior do que o que referiste e não está relacionado com encriptações, snifs de pacotes, nem nada parecido.

Imagina que trabalhas num local onde muita gente acede à net, (uma faculdade ou assim) e começas a snifar cookies. É uma festa, entras nas contas de quem seja... Concordo que se calhar não deve ser o principal problema de segurança, mas não deixa de ser um problema.

Parece que não há mesmo maneira dos cookies serem seguros.  :dontgetit:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Isso é mais ou menos o que tenho agora, e tem o problema de alguém apanhar o cookie e ficar a saber a hash, passando a poder imitar o utilizador legítimo...

? ? ? ? os cookies são servem mesmo para um utilizador chegar e já estar autenticado, se não é isto que se pretende então nao os deves usar. concepcionalmente diminui a segurança do utilizador, mas isso é o proprio conceito em si.

Imagina que trabalhas num local onde muita gente acede à net, (uma faculdade ou assim) e começas a snifar cookies. É uma festa, entras nas contas de quem seja... Concordo que se calhar não deve ser o principal problema de segurança, mas não deixa de ser um problema.

Isso não é com os cookies, é com tudo... é o mesmo se não os usares, as passwords podem ser snifadas. Se és paranoico em relação a segurança usa SSL.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso não é com os cookies, é com tudo...

Nunca mais uso a net! :cheesygrin:

Pá, tava a ver se me estava a escapar alguma coisa, ou se acarretavam mesmo esse risco... Tenho que ver isso do SSL, 10q

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso não é com os cookies, é com tudo...

Nunca mais uso a net! :cheesygrin:

Pá, tava a ver se me estava a escapar alguma coisa, ou se acarretavam mesmo esse risco... Tenho que ver isso do SSL, 10q

lol, é que é mesmo isso. Se tens essa paranoia nao uses internet.

Pa... se não for uma coisa seria tipo pagamentos, transferencias de dinheiro ou coisas do estilo não te metas nisso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa do hash é boa, mas mesmo assim é preciso uma forma de saber qual a id do utilizador tipo guardar o username.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa do hash é boa, mas mesmo assim é preciso uma forma de saber qual a id do utilizador tipo guardar o username.

????

pegas no hash que é único na tua bd e vez a qual utilizador corresponde.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isto só se aplica em computadores publicos certo? Quem é que num computador publico vái ligar o "remember me?" ? :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa do hash é boa, mas mesmo assim é preciso uma forma de saber qual a id do utilizador tipo guardar o username.

????

pegas no hash que é único na tua bd e vez a qual utilizador corresponde.

E se a hash não for única?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa do hash é boa, mas mesmo assim é preciso uma forma de saber qual a id do utilizador tipo guardar o username.

????

pegas no hash que é único na tua bd e vez a qual utilizador corresponde.

E se a hash não for única?

Mas é que a hash é única. Em primeiro lugar porque a probabilidade de esta se repetir é infima... infima digo tipo na ordem dos 10^-15 ou coisa parecida, isto para nao dizer mesmo menos.

Anyway... Mesmo que acredites em Deus e num milagre desses, se a guardares na base de dados sendo a hash o indice da tabela, então tem obrigatoriamente que ser unica, é o que é feito em todo o lado.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não podes ir pela unicidade da hash, porque não é.

Penso que existe uma Lei de Murfy que diz "Se alguma coisa pode correr mal então irá acontecer."

É a mesma coisa que jogar no euro milhões. A probabilidade de te calhar a ti é aproximadamente 0, mas a probabilidade de calhar a um dos milhões que jogaram já é grande.

A hash deverá ter uma associação ao user que a está a utilizar.

E é importante que essa hash seja gerada para cada autenticação de forma diferente, é como se fosse uma sessão.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas shumy, os teus dois paragrafos contradizem-se. Lá por ser gerado de forma diferente com base no unixtime e no username que é o que se costuma fazer, não quer dizer que são diferentes. Um hashing não é uma função injectiva, nunca pode ser já que o conjunto de chegada é finito e o de partida não.

Mas porque estamos a falar de coisas estupidamente improvaveis, isso não chega a acontecer, nem pode porque, se os hash forem guardados numa base de dados e se esta estiver devidamente normalizada estes servem de indices, e como tal não podem ser duplicados.

Cabe ao programador decidir o que fazer: código de erro personalizado, ou nada. Eu prefiro a segunda pois:

1.dá menos trabalho

2.nunca vai ser usada :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É verdade, se o hash for sempre gerado quando a pessoa é logada, caso o cookie seja roubado, vai ser só até a pessoa logar-se novamente e não existe o perigo de serem roubados dados do utilizador, acho que é a melhor escolha. Seria criada usando o que? o indice mais a password? o indice mais username? qual acham que seria o mais adequado?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

pa... eu faria qq coisa tipo

$time=time();
$hash = md5($time.$username);

Depois a variavel $hash podia servir indice na tabela dos cookies, ou podias mete-la numa coluna da tabela dos utilizadores como preferires.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem... se analisarmos o funcionamento dos cookies, um random serve, porque os cookies não são gerados pelo cliente.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Epá, para evitar o roubo de sessões, podes usar isto tudo para verificar o browser:

md5(serialize(array(md5($_SERVER['HTTP_USER_AGENT']), md5($_SERVER['HTTP_ACCEPT_LANGUAGE']), md5($_SERVER['HTTP_ACCEPT_ENCODING']), md5($_SERVER['HTTP_ACCEPT_CHARSET']))))

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu acho que ainda não perceberam.

O hash não serve para nada, é tão bom como um número aleatório.

Porque?

Fazes md5(xpto) = Y dando um resultado não invertivel, e mandas na cookie ( Y ) para o browser cliente.

O Browser normalmente não processa a cookie, e portanto não é dinâmico, a sessão pode ser roubada apanhando Y, independente do que venha.

Para confirmar a identidade é necessário uma função invertivel para cifrar, e o cookie deveria ser criado a cada chamada ao servidor. Só assim evitavas ataques por replay.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então o que sugeres? Não usar cookies e fazer um site em html sem php? Tem de haver uma forma minimamente segura de fazer as coisas! Além disso não deve ser assim tão fácil de roubar cookies...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu acho que ainda não perceberam.

O hash não serve para nada, é tão bom como um número aleatório.

Porque?

Fazes md5(xpto) = Y dando um resultado não invertivel, e mandas na cookie ( Y ) para o browser cliente.

O Browser normalmente não processa a cookie, e portanto não é dinâmico, a sessão pode ser roubada apanhando Y, independente do que venha.

Para confirmar a identidade é necessário uma função invertivel para cifrar, e o cookie deveria ser criado a cada chamada ao servidor. Só assim evitavas ataques por replay.

Acho que não percebeste o que quis dizer. A verificação seria feita assim:

if(md5(serialize(array(md5($_SERVER['HTTP_USER_AGENT']), md5($_SERVER['HTTP_ACCEPT_LANGUAGE']), md5($_SERVER['HTTP_ACCEPT_ENCODING']), md5($_SERVER['HTTP_ACCEPT_CHARSET'])))) != $r['verify']) die('Roubar sessões é feio meu menino.');

E o $r['verify'] seria o md5(serialize(array(md5($_SERVER['HTTP_USER_AGENT']), md5($_SERVER['HTTP_ACCEPT_LANGUAGE']), md5($_SERVER['HTTP_ACCEPT_ENCODING']), md5($_SERVER['HTTP_ACCEPT_CHARSET'])))) guardado na bd aquando do login.

Isto iria despistar em parte os cookies roubados, limitando o acesso a aquele user agent específico e às características daquela instalação/compilação do browser.

Claro está, isto não é necessário se usarmos SSL.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não estou a dizer que é facil roubar, porque na verdade o que se está a discutir aqui é o facto do atacante estar numa posição preveligiada (na mesma rede) podendo mesmo falsificar o IP. Em uma situação normal de internet este caso não é regra.

Para dificultar um pouco deve-se verificar o IP de origem da chamada. O valor random não será nada mais do que um identificador de sessão, não serve como autenticação.

Mais protecção que isto só SSL. Existe por algum motivo.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu acho que ainda não perceberam.

O hash não serve para nada, é tão bom como um número aleatório.

Porque?

Fazes md5(xpto) = Y dando um resultado não invertivel, e mandas na cookie ( Y ) para o browser cliente.

O Browser normalmente não processa a cookie, e portanto não é dinâmico, a sessão pode ser roubada apanhando Y, independente do que venha.

Para confirmar a identidade é necessário uma função invertivel para cifrar, e o cookie deveria ser criado a cada chamada ao servidor. Só assim evitavas ataques por replay.

Acho que não percebeste o que quis dizer. A verificação seria feita assim:

if(md5(serialize(array(md5($_SERVER['HTTP_USER_AGENT']), md5($_SERVER['HTTP_ACCEPT_LANGUAGE']), md5($_SERVER['HTTP_ACCEPT_ENCODING']), md5($_SERVER['HTTP_ACCEPT_CHARSET'])))) != $r['verify']) die('Roubar sessões é feio meu menino.');

E o $r['verify'] seria o md5(serialize(array(md5($_SERVER['HTTP_USER_AGENT']), md5($_SERVER['HTTP_ACCEPT_LANGUAGE']), md5($_SERVER['HTTP_ACCEPT_ENCODING']), md5($_SERVER['HTTP_ACCEPT_CHARSET'])))) guardado na bd aquando do login.

Isto iria despistar em parte os cookies roubados, limitando o acesso a aquele user agent específico e às características daquela instalação/compilação do browser.

Claro está, isto não é necessário se usarmos SSL.

Exactamente a mesma coisa...

Isso quer dizer que o texto que serve de autenticação vem "clear" no HTTP, basicamente todas essas caracteristicas do browser da vítima. Quem apanha um cookie também apanha essas configurações no pacote HTTP.

Facilmente se falsifica uma chamada sazendo-se passar por um browser com caracteristicas especificas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

yaps... acho que nao vale a pena dispersarmos e perdermo-nos no meio de tanta cofusão.

O método que eu sugeri pode ser obviamente substituido por outro método de randomização, eu escolhi aquele simplesmente porque daquela forma string à qual o hash vai ser aplicado é sempre diferente ( a nao ser que um utilizador faça login duas vezes no mesmo segundo ) , erma mesmo só naquela de evitar hashs iguais de forma simples, ainda que isso como já disse atrás não seja problema.

Tudo o que interessa aqui é:

enviar um código ao um utilizador, evitar que esse seja reproduzivel e a unicidade pode ser segura no servidor.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora