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

nuno_couto

Caracteres perigosos

10 mensagens neste tópico

Boas.

Num script em php que recebe dados do utilizador, quer sejam por post ou por url, qual é a melhor forma de validar esses dados?

Não sei se este método que estou a usar é suficiente (penso que seja, mas só para algumas variaveis)

ctype_digit / ctype_alnum / ctype_alpha...

com uma lógica do tipo if(!ctype_alnum($var)) {die();}

Automaticamente, em termos de segurança, se um utilizador malicioso tentar enviar comandos pela variável que é transmitida, estes vão ser bloqueados porque necessitam de caracteres que estão fora dos ctype_alnum por exemplo...

Mas se eu quiser validar os dados de um campo em que o user pode escrever um texto, o que aconselham a fazer?

Basta remover os caracteres perigosos? E que caracteres são esses?

Outra questão é relativamente à validação de um campo de email, para verificar se o user escreveu algo com o formato nome@dominio.com...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

acho que esse tipo de validação não deve ser tao facil de fazer, acho que não existe função para isso. mas também acho desneessario te preocupares assim tanto quanto essas validações. se programares bem o script e tiveres atenção a todas as possiveis falhas que possa ter, n precisas de te preocupar com alguem introduzir codigo num campo que n é para isso. apenas certifica-te que esse conteudo n vai puder fazer mal ao site independentemente de ter codigo malicioso n...

quanto ao mail, usa expressões regulares para validares um campo desse genero. procuro no google pela expressão de como validar e-mails

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas não percebo a que te referes com "programar bem o script"...

O que eu li genericamente em todos os artigos sobre segurança é que a regra número um é validar toda e qualquer entrada de dados por parte do utilizador.

A única forma de me certificar que um código malicioso colocado p.ex num formulário por um user, não vai ser prejudicial ao site, ou não vai permitir que o utilizador tenha acesso a informação privada etc etc... é validando esse input de dados.

P.ex, se ele introduz dados num campo de login, user e pass, deves fazer sempre mysql_real_escape_string($user) e mysql_real_escape_string($pass) para evitar mysql injection.

Mas para alem disso existe o "code injection", que permite p.ex ler ficheiros aos quais o utilizador não deveria ter acesso.

Por isso penso que se "retirarmos" os caracteres necessários à execução do código, e que não fazem falta à introdução de um texto p.ex estamos a prevenir...

Estou enganado?

Só não sei ao certo quais são os caracteres que, sendo retirados, anulam a possibilidade de introduzir qualquer comando malicioso...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

o que eu quis dizer com programar bem o script é +- o seguinte, por exemplo, retirado do manual php:

Example 2. An example SQL Injection Attack

<?php
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);

// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// This means the query sent to MySQL would be:
echo $query;
?> 

encontrei isto na parte sobre essa função que falaste mysql_real_escape_string() porque não tinha conhecimento e nunca usei... é obvio que o código acima, como eles mostram pode dar problemas, mas se tu pensares no que fazes, podes não precisar de usar o mysql_real_escape_string().

No exemplo acima, isto serve para ver se as nossas credencias de login estão correctas. Mas eu faço antes da seguinte maneira:

1) Saco apenas a password do base dados que esta codificada com uma hash md5ou sha1.

2) Converto a password inserida pelo utilizador para a respectiva hash

3) Comparo-as.

Como vês, n adianta nada o utilizar por algo malicioso na password porque o que quer que seja vai ser convertido para uma hash e essa propria hash nem se quer faz parte da query a base de dados, mas sim de uma instrução de comparação do PHP. Logo não ia ter o mesmo tipo de problemas que no script acima.

O que quero dizer é que para existerem possiveis "code injections" o script tem de ter falhas para isso, tem de estar programado de forma que isso seja possivel, se não houver um buraco para la, não precisas de tantas validações porque mesmo que seja inserido codigo malicioso por alguem, ele não irá conseguir fazer nada com ele, simplesmente, porque da maneira que o script esta programado, tal não ira ser possivel...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Concordo com o que o Nazgulled...  nuno_couto se quiseres aprender mais sobre segurança só precisas de procurar no google por "Segurança no PHP" eu aprendi tudo sobre segurança sozinho porque me esforçei muito tive que fazer um monte de pesquisas no google.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não discordo totalmente do Nazgulled.

A forma como o script está feito é muito importante.

kingless... Eu já li imenso sobre segurança em PHP e penso que os meus scripts neste momento são bastante seguros.

Foi por ler bastante que concluí uma coisa. A maior fonte de problemas de segurança (se não for praticamente a única) é a parte em que, de alguma forma, o script executa algo que utiliza dados introduzidos pelo utilizador (um site em html - só client side não tem problemas de segurança).

E foi por ler bastante que comecei a validar toda a informação que entra apartir do utilizador. Por exemplo, se os nomes de utilizador para login são obrigatoriamente letras e números, faço uma verificação do tipo if(!ctype_alnum($user)) {e aqui coloco a acção do erro}...

Se os dados vão ser usados para query´s na BD, uso o mysql_real_escape_string, embora tambem faça como o nazgulled... tambem uso a pass encriptada e converto-a numa hash antes de comparar.

Mas por outro lado, o user name não está encriptado. Vou procurar na BD pelo conjunto user + hash da pass... e se não "filtrar" o conteúdo do formulário user, sujeito-me a sql injection.

Foi por tudo isto que coloquei esta questão, que se aplica sobretudo a textos de maior dimensão introduzidos pelo utilizador.

Se for possível remover uma lista de caracteres (só falta saber exactamente quais) - os caracteres que permitem executar comandos de forma maliciosa, era uma segurança extra, e se isso fosse usado em simultaneo com o mysql_real_escape_string, os dados entrariam com segurança na BD, evitando tanto a possibilidade de sql injection como code injection.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu nunca utilizei esta função if(!ctype_alnum($user)) { } e também utilizei  mysql_real_scape_string(); e os meus scripts não deixam de estar seguros...

Aqui deixo-te algumas dicas de segurança:

-Nas "forms" tens que utilizar  strip_tags(); para apagar qualquer tipo de tag HTML

-Nas "textares" tens que utilizar strip_tags(); se não quiseres nenhum tipo de tag html ou então  html_special_chars(); se quiseres que a textarea aceite tags html mas que transforme as tags em caracteres especiais do html exemplo:  "<" vai se transformar em "&lt"  e  ">" vai se transformar em "&gt" e assim vai...

-No input das URL's (exemplo http://site.com/index.php?input=bla bla bla)  tens que utilizar  addslahes(); se  as "magic_quotes" tiverem OFF.

e também não deves permitir o input destas tags  <script> <meta><embed><object><applet><iframe><form><onmouseover><style><img><a >

-Nos Querys a mysql em vez de executares o Querys assim 

$query = "SELECT coluna FROM tabela"; 

mysql_query( $query ); 

executa assim:

$query = "SELECT coluna"

              . "\nFROM tabela";

mysql_query( $query );

Isto ajuda a evitar SQL Injections e não te esquecas de utilizar addslashes(); quando tiveres a inserir um valor a MySQL e stripslahes(); quando tiveres a ir buscar um valor a SQL.

Escrevi isso muito rapido não sei se vais entender...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

-Nas "textares" tens que utilizar strip_tags(); se não quiseres nenhum tipo de tag html ou então  html_special_chars(); se quiseres que a textarea aceite tags html mas que transforme as tags em caracteres especiais do html exemplo:  "<" vai se transformar em "&lt"  e  ">" vai se transformar em "&gt" e assim vai...

Não querias antes escrever htmlspecialchars();  ?  :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim isso... como eu disse acima

(...)

Escrevi isso muito rapido não sei se vais entender...

:P mesmo assim obrigado por reparares neste pequeno pormenor.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas por outro lado, o user name não está encriptado. Vou procurar na BD pelo conjunto user + hash da pass... e se não "filtrar" o conteúdo do formulário user, sujeito-me a sql injection.

mas lá esta... tudo isso depende de como o script é feito... aqui, tens duas hipoteses:

1) comparas o nome inserido directamente na bd usando sql sujeitando-te assim a sql injection

2) sacas o username e comparas normalmente com php (o que eu costumo fazer)

se optares por 2, ja n é possivel existir qq tipo de sql injection (neste caso).

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