View Full Version : Que segurança necessito? PHP+MySQL


DarkWolfXP
10-02-2008, 15:29
Boas, estou a construir/remodular um site de negócio:003:, sendo o site destinado para uma area relacionado com €€, eu pretendia protegê-lo de falhas/ataques que se possam aproveitar para "estragar" o meu site..?
Eu gostaria de saber: como me protejo de SQL injection; qual a encriptação de pass que me recomendam; como proteger das outras falhas (julgo que existem mts falhas que se possam aproveitar para danificar um site, mas qual as falhas mais vulgares/básicas que existem e como proteger?);
Obrigado pela atenção
Cumprimentos
DarkWolfXP

HorusIcarus
10-02-2008, 16:55
O melhor será adquirir (ou não) um sofware especializado no assunto, não me recordo do nome,mas há um que é o líder,é o melhor amigo de um Web Designer, detecta todos os meios possíveis de 'exploit' a um determinado site/rede.
Em relação à encriptação, é óbvio que a mais segura será MD5 ,mas a segurança não está só na encriptação,também está no caminho entre a aquisição da password > Encriptação > Envio para a DB . Vou procurar o nome do Soft, se encontrar já o deixo aí.

AliFromCairo
10-02-2008, 16:57
Boas, no que diz respeito à encriptação, dá uma vista de olhos aqui (http://phpsec.org/articles/2005/password-hashing.html).

DarkWolfXP
10-02-2008, 17:04
Obrigado a todos pelas respostas!
@AliFromCairo
Esse site vai m ser muito util!

@HorusIcarus
Se conseguisses me dizer o nome desse programa era perfeito! Parece ser tudo o que preciso numa só ferramenta :D

Hipnoted
10-02-2008, 19:35
Podes sempre fazer download da 11ª edição da revista PROGRAMAR (http://www.portugal-a-programar.org/revista-programar/edicoes/Revista_PROGRAMAR_-_11a_edicao_Novembro_2007.pdf) que tem lá um artigo sobre vulnerabilidades e segurança em PHP.

Senão podes aceder directamente ao artigo aqui (http://www.portugal-a-programar.org/forum/index.php/topic,21783.0.html).

hasta.g5
10-02-2008, 19:37
Outra coisa também muito importante é usares funções para evitarem SQL injections.
No caso de usares PHP e MySQL, tens a mysql_real_escape_string() (http://pt2.php.net/mysql_real_escape_string).

DarkWolfXP
10-02-2008, 20:29
@Hipnoted
Obrigado! Eu já tinha visto o nome dessa revista aki na Techzone mas por acaso nunca a vi. Esse artigo tá mt esclarecedor :D, vou-o ler com mais atenção quando tiver tempo!

@hasta.g5
Pois, essa string ainda n o tenho no meu site o_o estava, aberto a SQL injection ;o.
Encontrei este site : http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php que fala sobre SQL injection, e como prevenir com mysql_real_escape_string(), também vou-o ler com mais calma quando tiver tempo


P.S- Segundo o artigo do Hipnoted:
". Quando falo de "criptografia segura", refiro-me a algoritmos considerados seguros para o armazenamento de dados sensíveis, como os algoritmos SHA-256 e AES por exemplo, em detrimento de "criptografia insegura", como os algoritmos MD4, MD5, SHA-1, entre outros.
Refere que MD5 é uma criptogragia insegura... será que devo usar o SHA-256?


Obrigado a todos pelas respostas :)
Cumprimentos
DarkWolfXP

hasta.g5
11-02-2008, 02:39
MD5 encripta em 128 bits, SHA-1 em 160 e SHA-256 em 256. A partir daí vê-se qual o mais seguro. Agora falta saber se vale a pena usar-se uma encriptação tão grande, em páginas com muito movimento pode ser um problema.

De qualquer das maneiras, fica aqui a referência às funções hash, (http://pt2.php.net/manual/en/ref.hash.php) que é o que se usa para SHA-256, usando a função hash_init('sha256'); (http://pt2.php.net/manual/en/function.hash-init.php).

Não te esqueças que segurança não é só encriptar as passwords, e mesmo isso só é encriptado quando chega ao lado do servidor. Há muitas mais coisas que podes proteger, como por exemplo, atribuires um ID ao teu formulário para que previnas que alguém execute um a partir do próprio PC, manter ficheiros com informação importante como dados de ligação a bases de dados fora do httpdocs, etc..

DarkWolfXP
11-02-2008, 09:43
Estou a ver, acho então o MD5 melhor...
Vou também tentar atribuir IDs aos meus formularios :)
Obrigado a pela atençao :D

slack_guy
11-02-2008, 11:26
Vou também tentar atribuir IDs aos meus formularios
Atribuir e validar :-)

Qualquer coisa como:

1º no servidor crias um ID e registas (num ficheiro, BD) esse ID com uma validade de X tempo (esse ID pode ser, por exemplo, uma hash do IP que fez o pedido, mais a data-hora, mais o ID do user e mais qualquer coisa que te lembres e que garanta que o ID seja único);
2º Crias o formulário com esse ID <form name='xpto' id='12345ABC876'....>
3º Quando o formulário é enviado de volta para o servidor, validas o ID contra a lista de IDs válidos.
Se não for válido, tens duas opções:
3.1 mostras um erro, mas não terminas a sessão;
3.2 terminas a sessão e redireccionas imediatamente para logout.
4º Se o formulário foi gravado com êxito, eliminas o ID da lista.

DarkWolfXP
15-02-2008, 22:05
Boas, hoje como fiquei com mais tempo livre decidi implementar as medidas de segurança.
As passwords já estão encriptadas...
O problema surge agr na prevenção do SQL injection, eis o erro que me aparece ao fazer login:

Warning: mysql_real_escape_string(): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) in /home/www/boostbux.info/login.php on line 29

Warning: mysql_real_escape_string(): A link to the server could not be established in /home/www/boostbux.info/login.php on line 29

P.S-O meu site está alojado num servidor com o pacote Free Package, e possui limitações... Será que é por isso?

slack_guy
15-02-2008, 22:19
P.S-O meu site está alojado num servidor com o pacote Free Package, e possui limitações... Será que é por isso?
Não sei se é por isso ou não, mas eu sugiro-te fortemente que não faças isso num servidor remoto. Entre outras razões, porque não conheces todo o software que está instalado e como está configurado e de que modo é que isso influencia a tua aplicação.

Se possível, instala um servidor web (Apache) e o MySQL no teu computador. Faz as 'avarias' todas na tua máquina. Além de te facilitar enormemente o trabalho (porque sabes o que está instalado, onde e como está configurado) não te arriscas a 'efeitos colaterais' num servidor que não é teu.

DarkWolfXP
15-02-2008, 22:21
Bem isso faz-se num instantesinho :lol:, como ao principio o site estava alojado no servidor ca de casa, possui ja o Xampp configurado, daki uns minutos já posto aki nvdd.
Obrigado pela dica

Já está a funcionar! Obrigado slack_guy! Foi um erro de transcrição quando passei a expressao mysql_real_escape_string(); eliminei a outra expressao que conectava com a base de dados :lol: -.-' isto é resultado dos exames!!! xD
Obrigado mais uma vez!
Vou agr meter os IDs nas forms ^^
Cumps

DarkWolfXP
16-02-2008, 09:47
Atribuir e validar :-)

Qualquer coisa como:

1º no servidor crias um ID e registas (num ficheiro, BD) esse ID com uma validade de X tempo (esse ID pode ser, por exemplo, uma hash do IP que fez o pedido, mais a data-hora, mais o ID do user e mais qualquer coisa que te lembres e que garanta que o ID seja único);
2º Crias o formulário com esse ID <form name='xpto' id='12345ABC876'....>
3º Quando o formulário é enviado de volta para o servidor, validas o ID contra a lista de IDs válidos.
Se não for válido, tens duas opções:
3.1 mostras um erro, mas não terminas a sessão;
3.2 terminas a sessão e redireccionas imediatamente para logout.
4º Se o formulário foi gravado com êxito, eliminas o ID da lista.

Bem estive analisar isto detalhadamente e fiquei perante 2 questões:
-Porque é que o ID criado na BD tem de ser temporario, e como crio um ID temporario?
-Se o ID não for constante a ID da form tb terá de variar... como irei fazer isso?

Obrigado desde já a atenção disponibilizada :009:
Cumps

Hostx
16-02-2008, 13:50
Tens o NeedSecure que proteje a area de membros com as password etc.

Tens aqui uma versão: NeedSecure Pro v1.1.4

DarkWolfXP
16-02-2008, 16:28
Bem esse software é interressante, mas é a pagar... Gostaria de seguir o que o slack guy me propos... mas as minhas duvidas mantem sw:005:
Cumps

slack_guy
16-02-2008, 19:35
Bem estive analisar isto detalhadamente e fiquei perante 2 questões:
-Porque é que o ID criado na BD tem de ser temporario, e como crio um ID temporario?
-Se o ID não for constante a ID da form tb terá de variar... como irei fazer isso?

1. O ID não tem de ser temporário. Mas como tem um 'prazo de validade' de X minutos/horas, se não o apagas da BD, vais ficar com um monte de entulho :-)

2. Se o ID é constante (isto é, um valor constante), não vale a pena teres ID ;-) A ideia é que seja sempre diferente.

Assumindo que os sistemas de autenticação (login) e de validação (acesso à página/recurso pedido consoante o perfil de acesso do utilizador 'logado') estão a funcionar, vamos lá ver se consigo explicar-te com mais detalhe:

§ o utilizador entrou no sistema e criaste uma sessão (session).

§ os dados da sessão estão, se não alteraste, armazenados num ficheiro temporário algures no computador - agora não interessa saber onde; interessa apenas saber que estão guardados num ficheiro e não na BD.

§ O utilizador abre a página com o formulário para encomendar bananas.


De modo a garantir que esse formulário é válido - criado pela tua aplicação - e que não há re-post do formulário, crias um $ID_FORM baseado em variáveis que te assegurem que o $ID_FORM é único. Por exemplo, calculas o MD5 do ID_UTILIZADOR + DATA + HORA + NOME_FORM + IP_REMOTO + O_QUE_QUISERES.

Adicionas o $ID_FORM à sessão do USER, com a seguinte estrutura (exemplo):

id_form => {
expira_em => data_hora,
usado => nao
}

Ao criares o formulário, crias um campo hidden:

<input type='hidden' name='id_form' value='$ID_FORM' />



§ Quando o utilizador envia o formulário, a primeira operação que fazes é validar o campo 'id_form':

$id_form existe na sessao do utilizador?

Não: formulário não é válido
Sim: Verificas se o valor de 'expira_em' <= data_hora_actual e (se não quiseres diferenciar mensagens de erro) se 'usado' == 'nao'

Não: A validade expirou ou está a fazer re-post do formulário
Sim: validas os restantes campos do formulário.
No final, tens duas opções:

Eliminas o id_form da sessão;
Alteras o valor de 'usado' para 'sim'




Fui mais claro? ou ainda ficou mais enrolado? :-)

DarkWolfXP
16-02-2008, 20:27
Bem, segundo o que percebi terei de proceder os seguintes passos:
-Criar um $ID_form com base em informaçoes que quiser...
-Após a criação deste ID_form adiciono ao cookie do utilizador por exemplo:

[CODE]setcookie("IDForm",$ID_Form,time()+7776000);[CODE]


Agora não percebi esta parte
Adicionas o $ID_FORM à sessão do USER, com a seguinte estrutura (exemplo):

Código:
id_form => {
expira_em => data_hora,
usado => nao
}
Desculpa :s mas, eu sou fresco nisto -.-', nunca vi uma estrutura dessas até a este momento...

-Adiciono o $ID_Form ao valor do formulario
-Verifico quando o utilizador envia o formulario se o ID do formulario é igual ao Cookie do utilizador

Julgo que seja isso, agr aquela parte é que não percebi :confused:

slack_guy
16-02-2008, 22:50
-Criar um $ID_form com base em informaçoes que quiser...
Esse ID crias com a função md5() (http://pt2.php.net/md5) ou sha1() (http://pt2.php.net/sha1) ou outra.

-Após a criação deste ID_form adiciono ao cookie do utilizador por exemplo:
Bom, podes trabalhar com cookies, mas eu estava a falar de sessões (http://pt2.php.net/session)

Desculpa :s mas, eu sou fresco nisto -.-', nunca vi uma estrutura dessas até a este momento...
My bad :-( essa estrutura é Perl (hábitos :-) )
Poderia ser um array:

$forms = array(
id_form = array(
expira_em => 'data_hora',
usado => 'nao',
)
);


-Adiciono o $ID_Form ao valor do formulario
Adicionas o $ID_FORM ao valor de um campo do tipo hidden.

-Verifico quando o utilizador envia o formulario se o ID do formulario é igual ao Cookie do utilizador
Verificas se o valor que vem do campo hidden é igual ao valor que tens na sessão.
Repara que não mandas o ID_FORM para cookies, apenas para o valor de um campo hidden. Ou seja, o utilizador nunca terá no seu computador a estrutura de dados que referi mais acima. Caso contrário, todo este trabalho era desnecessário. Essa estrutura fica na variável de sessão, que é escrita num ficheiro no servidor. A única coisa com que o utilizador pode 'brinca' é com o valor do campo hidden. E nesse caso, não tem muito com que se entreter :-)

Resumindo: para implementares isto tens de aprofundar o teu conhecimento sobre o mecanismo de manuseamento de sessões em PHP.

Nota sobre cookies: pessoalmente sou adepto de registar em cookies o mínimo possível de dados. Regra geral, o mínimo é apenas o ID da sessão. Tudo o resto pode dar azo a coisas 'desagradáveis'.

DarkWolfXP
17-02-2008, 00:12
Boas... Eu não estou a conseguir :005: desculpa estar a puxar a tua paciencia ao limite slack_guy :(, Mas...
Repara que não mandas o ID_FORM para cookies, apenas para o valor de um campo hidden. Ou seja, o utilizador nunca terá no seu computador a estrutura de dados que referi mais acima. Caso contrário, todo este trabalho era desnecessário. Essa estrutura fica na variável de sessão, que é escrita num ficheiro no servidor.
Queres dizer que não devo de fazer o seguinte?
setcookie("IDForm",$ID_Form,time()+7776000);

Quando dizes
Adicionas o $ID_FORM à sessão do USER, com a seguinte estrutura (exemplo):
$forms = array(
id_form = array(
expira_em => 'data_hora',
usado => 'nao',
)
);

Eu nunca mexi com arrays, não percebo o objectivo dakela expressão acima, dizes que é para adicionar o ID_Form á sessão/Cookie mas tb dizes k n se deve adicionar o ID_Form ao Cookie :S
Eu só não percebo como é que vou inserir o ID_Form no utilizador o resto eu entendi perfeitamente :sad:
Desculpa pelo incomodo slack_guy...
Cumps

slack_guy
17-02-2008, 00:34
Bom, confesso que eu e o PHP não nos damos bem :-S
Tens de investigar como lidar em PHP com (tens os links no meu post anterior):
- estruturas de dados;
- sessões
- funções de criptografia: crypt(), md5(), sha1(), ...

Eu só não percebo como é que vou inserir o ID_Form no utilizador o resto eu entendi perfeitamente
Não é no utilizador. É na variável de sessão (da sessão) do utilizador (tens de investigar como fazer isso em PHP).

DarkWolfXP
17-02-2008, 00:39
Boas, vou seguir o teu conselho, vou tentar verificar isso das Sessoes... Eu sei que podia optar por sessoes com $_Sessions, mas neste momento estou com Cookies, pelo qual para adicionar o ID_form no cookie iria proceder ao seguinte
setcookie("IDForm",$ID_Form,time()+7776000);, mas como referes isso seria em vão... Vou ver isso dos sessions ^^
Obrigado pela atenção foi mt util!
Cumps
DarkWolfXP