Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Galera , to criando uma função pra segurança , e to com o seguinte problema ..
eu do str_replace .. ele nao substitui o que tem no array que e invalido , pelo espaço ..
aqui vai o codigo
function isMatch($dados) {
$verifica = preg_replace('/[^a-zA-Z0-9]+/', '', $dados);
$cant = array("select","drop","insert","declare","exec","where","from","drop table","--","*","'","+","truncate","del","union","content");
$rpl = "";
$verifica = str_replace($cant,$rpl,$dados);
$is_valid = "a-z A-Z 0-9";
if(!$verifica){
echo '<script language="javascript"> alert("Não Use Characters Ilegais \n Characters Validos:: '.$is_valid.'"); </script>';
}
return preg_replace('/[^a-zA-Z0-9]+/', '', $dados);
}
select = invalido o resultado tinha que ser em branco , ou seja pelo replace ali ..
mais ta voltando "select" ..
quero que ele remova a palavra que conten no array e faça a verificação dos characters com preg_replace ... se e compativel com a-zA-Z0-9 .. se nao for ele substitui e manda aquele alerta .. :D
vlw
Fewdox
:D e se nao tiver mysql instalado , for PgSQL , ou mysqli
esquece essa função que remove dados. eu tenho direito de escrever qualquer texto. Imagine se o fórum bloqueasse palavras como SELECT, DELETE... o q e seria o fórum de SQL?
veja o tópico "Segurança em PHP", no subbfórum Desagios.
Ou leia sobre seu SGBD e veja como é feito o escape de caracteres.
addslashes() basta. Keep it simple =)
:seta: ModSecurity
Vlw João , VO dAR uma olhada qualquer coisa posto aqui :D
Beraldo .. Mais na pagina de cadastro que eu to fazendo , ou seja coisa que o cara nao vai presisar usar "select etc .." ou alguma expressão SQL ..
Lucas . addslashes .. nao so basta .. depende do tipo de injection . tem injection que nen leva aspas ..
creio que um mysql_ecape_string ou mysql_real_escape_string . ia ajudar tbm ..
vlw pelo concelho ai pesoal :D
>
Beraldo .. Mais na pagina de cadastro que eu to fazendo , ou seja coisa que o cara nao vai presisar usar "select etc .." ou alguma expressão SQL ..
Isso não justifica remoção de informações da mensagem do usuário.
E se alguém quiser postar um trecho em inglês com essas palavras?
>
Lucas . addslashes .. nao so basta .. depende do tipo de injection . tem injection que nen leva aspas ..
creio que um mysql_ecape_string ou mysql_real_escape_string . ia ajudar tbm ..
é isso que a função faz:
>
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
fonte: http://php.net/manual/en/function.mysql-real-escape-string.php
>
Lucas . addslashes .. nao so basta .. depende do tipo de injection . tem injection que nen leva aspas ..
creio que um mysql_ecape_string ou mysql_real_escape_string . ia ajudar tbm ..
Agora estou surpreso...
Sempre utilizei simples addslashes() contra sql injection (quero dizer, caso o magic_quotes esteja desativado, e está). Como o cara pode fazer uma Sql Injection sem utilizar áspas simples ou duplas?
$str = addslashes($_POST['str']);
$sql = "SELECT `user` FROM `tests` WHERE str='$str'";
Como o cara vai fazer para fechar a string $str e, assim sendo, realizar uma sql injection?
Dê uma olhada em todo o tópico que você irá entender: :seta: http://forum.imasters.com.br/index.php?/topic/276729-seguranca-em-php/
>
Dê uma olhada em todo o tópico que você irá entender: :seta: http://forum.imasters.com.br/index.php?/topic/276729-seguranca-em-php/
Li ele todo e... nada me respondeu...
Me de um exemplo de como o cara pode fazer um SQL INJECTION se eu utilizo addslashes()...
Pois não:
<?php
mysql_connect("localhost","root","");
if(get_magic_quotes_gpc())
{
$max=$_GET['max'];
}else{
$max=addslashes($_GET['max']); }
print "select * from mysql.user where max_connections=".$max;
$q=mysql_query("select * from mysql.user where max_connections=".$max);
$a=mysql_fetch_array($q);
print_r($a);
?>
Saída: localhost/escape_test.php?max=0+and+sleep(10)
Isso causa um breack no banco de dados por 10 segundos, atrasando assim a consulta e consequentemente o carregamento da página.
$q=mysql_query("select * from mysql.user where max_connections=".$max);
Só uma pergunta: eu nunca faria uma query assim, faria algo do tipo:
$query = mysql_query("SELECT * FROM mysql.user WHERE max_connections='$max'");
E leria assim: "... WHERE max_connections='0+and+sleep(10)'", e seria lido como um simples texto, ou estou errado?O Alaerte se refere a um campo inteiro, por isso não usa aspas.
Aí nem addslashes resolve. Nesse caso, você tem que usar is_numeric(), por exemplo.
Verificar tipo de variável é MUITO importante. É uma pena o PHP ser tão fracamente tipado... :P
Só uma pergunta: eu nunca faria uma query assim, faria algo do tipo:
$query = mysql_query("SELECT * FROM mysql.user WHERE max_connections='$max'");
Depende muito do programador, usar esse método ou não saca...
Faça uma experiência, faça a consulta normal,
$query = mysql_query("SELECT * FROM mysql.user WHERE max_connections='$max'");
e depois usando a variável direto, e você verá
O Alaerte se refere a um campo inteiro, por isso não usa aspas.
Isso aí Beraldo :joia:
Desculpem minha ignorância :), mas não entendi...rs
Por exemplo, fui em um blog wordpress de testes e pus esse código:
<?php
include('conectar.php');
if(get_magic_quotes_gpc()){
$max=$_GET['max'];
}else{
$max=addslashes($_GET['max']);
}
print "select * from wp_posts where max_connections=".$max;
$q=mysql_query("select * from wp_posts where max_connections=".$max);
$a=mysql_fetch_array($q);
print_r($a); ?>
Lá em conectar.php, há isso:
<?php
// informações sobre o banco de dados
$db['servidor do banco de dados'] = "----";
$db['usuário do banco de dados'] = "----";
$db['nome do banco de dados'] = "----";
$db['senha do banco de dados'] = "----";
// conecta com o banco de dados
mysql_connect($db['servidor do banco de dados'], $db['usuário do banco de dados'], $db['senha do banco de dados'])
or die("Não foi possível conectar-se com o banco de dados. Verifique as definições das variáveis do arquivo. Erro: <b>".mysql_error()."</b>");
// seleciona o banco de dados
mysql_select_db($db['nome do banco de dados'])
or die("Não foi possível selecionar o banco de dados. Verifique as definições das variáveis do arquivo. Erro: <b>".mysql_error()."</b>");
E bem... nada ocorreu... não deixou o script lento, e apenas apareceu:
select * from wp_posts where max_connections=0 and sleep(10)
Ps.: Aqui onde estou os magic_quotes estão ativos, mas isso não deveria afetar em nada... o que estou fazendo de errado? rs
ok. aquilo foi um exemplo. a execução depende das configurações do servidor e das informações no BD.
a intenção é apenas mostrar que dados numéricos ficam fora de aspas, além de que TODOS os dados devem ser devidamente filtrados e validados
Vamos voltar à sua dúvida inicial, que nem mais lembro qual era... já foi solucionada? restam dúvidas?
não , estou esperando um filtro decente , o mod security que beraldo postou , ja estava habilitado aqui ..
>
não , estou esperando um filtro decente , o mod security que beraldo postou , ja estava habilitado aqui ..
"esperando"...
Já foi citado que não precisa remover palavras. Já foi citado um tópico que só trata desse assunto (Segurança em PHP, no sub-fórum de artigos).
Também há as funções mysql_real_escape_string, pg_escape_string e outras nativas dos respectivos SGBD's.
Ao meu ver, está tudo aí. Basta escolher. Há vários argumentos e várias soluções, inclusive as nativas dos SGBD's, que acredito serem as preferenciais.
>
:D e se nao tiver mysql instalado , for PgSQL , ou mysqli
Se você usar MySQLi ele pode escapar as aspas pra você sem o uso de funções.
para saber como dá uma olhada aqui: http://blog.thiagobelem.net/mysql/usando-o-mysqli-orientado-a-objetos/
>
Pois não:
<?php mysql_connect("localhost","root",""); if(get_magic_quotes_gpc()){ $max=$_GET['max']; }else{ $max=addslashes($_GET['max']); } print "select * from mysql.user where max_connections=".$max; $q=mysql_query("select * from mysql.user where max_connections=".$max); $a=mysql_fetch_array($q); print_r($a); ?>
Saída: localhost/escape_test.php?max=0+and+sleep(10)Isso causa um breack no banco de dados por 10 segundos, atrasando assim a consulta e consequentemente o carregamento da página.
O MySQLi tbm resolve esse problema, uma vez que você modifica a query com colocando a variavel para ser atribuida através do bind_param.
o Post acima mostra esse exemplo tbm.
>
ok. aquilo foi um exemplo. a execução depende das configurações do servidor e das informações no BD.
a intenção é apenas mostrar que dados numéricos ficam fora de aspas, além de que TODOS os dados devem ser devidamente filtrados e validados
Mas e se elas ficarem dentro, também funcionam e mesmo assim ainda dá para fazer SQL Injection?
Ps.: Caso positivo, por quê? O mysql_real_escape_string iria "concertar" isso?
>
Mas e se elas ficarem dentro, também funcionam e mesmo assim ainda dá para fazer SQL Injection?
Ps.: Caso positivo, por quê? O mysql_real_escape_string iria "concertar" isso?
elas quem? e dentro de onde?
não entendi
Nossa, realmente o que escrevi não faz sentido...rs
Bem, e se eu por as variáveis que irei usar na query em áspas simples, mesmo estas sendo valores numéricos, isso impediria exemplos como os mostrados por vocês?
Caso negativo, por quê? E mysql_real_escape_string(), impediria esse tipo de ataque?
Se você ler o manual de mysql_real_escape_string, verá que a função apenas insere barras invertidas. Ela não trata parâmetros de consulta
Veja estes testes
mysql> create table numeros(
-> numero int
-> );
Query OK, 0 rows affected (0.18 sec)
mysql> insert into numeros(numero) values(7), (42), (73);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from numeros where numero = 7;
+--------+
| numero |
+--------+
| 7 |
+--------+
1 row in set (0.01 sec)
mysql> select * from numeros where numero = '7';
+--------+
| numero |
+--------+
| 7 |
+--------+
1 row in set (0.00 sec)
mysql> create table numeros_decimais( numero decimal(5,2) );
Query OK, 0 rows affected (0.06 sec)
mysql> insert into numeros_decimais values(7.42), (73.07);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from numeros_decimais where numero = 7.42
-> ;
+--------+
| numero |
+--------+
| 7.42 |
+--------+
1 row in set (0.00 sec)
mysql> select * from numeros_decimais where numero = '7.42';
+--------+
| numero |
+--------+
| 7.42 |
+--------+
1 row in set (0.00 sec)
mysql>
Ou seja, mesmo sendo numérico, pode usar aspas. Porém não faz sentido tratar número como string (PHP faz isso, eu sei, mas não faz sentido). Números são números, strings são strings. É importante saber tratar cada um deles de forma adequada, não considerar tudo como string e o BD que se vire
Bem, fazendo sentido ou não, nesse caso iria impedir o usuário de fazer algo como nosso amigo Alaerte mostrou?
Como o Beraldo já disse, a solução foi proposta por diversas pessoas. Fazendo um resumo:
Fazendo isto você está seguro de injection.
Carlos Eduardo
Cara usa mysql_real_escape_string que você resolve o problema, não precisa usar esse tipo de função.