Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Pessoal, essa dá p/ dizer q é facil de mais, mas vamos lá....
como filtrar os dados recebidos de um formulário?
ou seja, você recebe do user uma string qualquer e remove tudo o que for indesejado, como (', ", <script>), só aceitando caracteres maiusculos, minusculos e numeros.
o usuário envia: ' or 1='1
e você devolde: or11
entenderam?
eu já fiz o meu aqui, no final eu mostro.
Um detalhe: "só aceita caracteres maiusculos, minusculos e numeros". Essa function está aceitando outros caracteres tbm.
Uma dica: Se você usar htmlspecialchars() não precisa usar addslashes(), assim você ganha em desempenho.
valew pelo post narizgudo!
Vlw pela dica =D
Eu fiz um teste aqui e olha soh o resutlado
echo addslashes(htmlspecialchars("' or 1=1")); // mostra >> \' or 1=1
echo htmlspecialchars("' or 1=1"); // mostra >> ' or 1=1
Se eu tirar o addslashes eu nao escapo ' nem " e nem outros caracteres especiais
function sqlinj($string) {
$string = strip_tags($string);
$string = htmlspecialchars($string);
$string = addslashes($string);
$string = str_ireplace("SELECT","",$string);
$string = str_ireplace("FROM","",$string);
$string = str_ireplace("WHERE","",$string);
$string = str_ireplace("INSERT","",$string);
$string = str_ireplace("UPDATE","",$string);
$string = str_ireplace("DELETE","",$string);
$string = str_ireplace("DROP","",$string);
$string = str_ireplace("DATABASE","",$string);
$string = str_ireplace("USE","",$string);
return $string;
}
vê se ta melhora htmlspecialchars() converte as ' em ' (se ENT_QUOTES for passado como segundo parâmentro na função), segundo a documentação do php, por isso que addslashes() não seria necessário, mas tudo bem.
aqui está o código do filro de dados ideal:
CODE
class Utils{
//caracteres permitidos
public static $chars = "1234567890abcdefghijlmnopqrstuvxzwykABCDEFGHIJLMNOPQRSTUVXZWYK";
//remove qualquer tipo de ataque
public static function secure($str){
$str = (string) $str; //obtem a string do parametro recebido
$arr_str = str_split($str); //quebra a string em um array
$num_chars = count($arr_str); //tamanho da string, poderia ser strlen($str) tambem
$new_str = ""; //cria uma nova string, que sera retornada
for($i=0 ; $i<$num_chars ; $i++){
if($arr_str[$i] !== ""){ //se a array nao é vazia
if(strpos(self::$chars , $arr_str[$i]) !== false){ //a string pertence ao conjunto permitido
$new_str .= $arr_str[$i]; //adiciona o caracetere a string q sera retornada
}
}
}
return($new_str); //retorna a string
}
}
assim você só pega os dados de um form e:
$data = Utils::secure($_POST['data']);
Bem, lá vai o meu:
$filtracao= getenv('REMOTE_ADDR');
$badwords =array(";","'","\"","*","union","del","DEL","insert","truncate","update","drop","sele","memb","set","$","wareh","%","--","+");
foreach($_POST as $value)
foreach($badwords as $word)
if(substr_count($value, $word) > 0)
die ("<center><ul><li><font color='red'><b>[ERRO]- Alerta: Caracteres inválidos.</b></font>
</li>
</ul>
</center>");Basta colocar no início do documento, assim todo caractere inválido que form enviado pelo metodo POST será impedido de acordo a regra. :D>
Bem, lá vai o meu:
$filtracao= getenv('REMOTE_ADDR');
$badwords =array(";","'","\"","*","union","del","DEL","insert","truncate","update","drop","sele","memb","set","$","wareh","%","--","+");
foreach($_POST as $value)
foreach($badwords as $word)
if(substr_count($value, $word) > 0)
die ("<center><ul><li><font color='red'><b>[ERRO]- Alerta: Caracteres inválidos.</b></font>
</li>
</ul>
</center>");Basta colocar no início do documento, assim todo caractere inválido que form enviado pelo metodo POST será impedido de acordo a regra. :D
belo código cara, a lógica é +/- essa, só q ali tu tá dando um die(), o que tem q fazer segundo desafio é receber os dados do form, tirar as impurezas e utilizar somente os caracteres validos, sem interromper a execução do script.
ou seja, o user manda nome='<script>alert(\'oi mundo\');</script>' você filtra isso usando apenas nome='scriptalertoimundoscript';
com mais umas linhas de código você consegue, tá no caminho fera http://forum.imasters.com.br/public/style_emoticons/default/grin.gif valew, t
Fácil amigo, basta juntar com a função que o Fabyo fez,ou com o do narizgudo, segue abaixo:
limpar.php
function anti_injection($sql)
{
// remove palavras que contenham sintaxe sql
$sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$sql);
$sql = trim($sql);//limpa espaços vazio
$sql = strip_tags($sql);//tira tags html e php
$sql = addslashes($sql);//Adiciona barras invertidas a uma string
return $sql;
}
//modo de usar pegando dados vindos do formulario
$nome = anti_injection($_POST["nome"]);
$senha = anti_injection($_POST["senha"]);
?>$badwords=array(";","'","\"","*","union","del","DEL","insert","truncate","update","drop","sele","memb","set","$","wareh","%","--","+");
foreach($_POST as $value)
foreach($badwords as $word)
if(substr_count($value, $word) > 0){
(file_exists('limpar.php')) ? (require('limpar.php')) : false;
anti_injection($_POST['data']);
}<?php
$input = "' or 1='1";
// Caracteres do mal
$badchars = str_split(" '*$\"\\=+-><@#%¨&{}[]");
// Strings do mal
$badstrings = array();
//UPERCASE
$badstringsu [] = 'SELECT';
$badstringsu [] = 'INSERT';
$badstringsu [] = 'UPDATE';
$badstringsu [] = 'TRUNCATE';
$badstringsu [] = 'DROP';
$badstringsu [] = 'USE';
$badstringsu [] = 'CREATE';
$badstringsu [] = 'RESET';// Reune todos os caracteres invalidos
$invalid = array_merge($badstringsu,$badstringsl,$badchars);
// Substitui todos os invalidos por ''
foreach($invalid as $v) {
$output = str_replace($invalid,'',$input);
}
echo $output;
?>mas o objetivo foi cumprido, a saída é como a do desafio.... hehehehe....
Só não entendi pra que invalidar o '='...
[ADICIONADO EM 2/5/2008:]
Bom, estudando melhor o assunto, achei melhor:
- não retirar palavras reservadas do SQL: SELECT, UPDATE, etc.
$input = "' or 1='1";
$input = strip_tags($input); // retirar tags php
$output = eregi_replace("[^a-z0-9ã-õá-úà-úãõâ-ûç,.;]", '', $input);
echo $output;
É isso.humm também ficou legal mangakah...
vou fazer um ante SI (sql injection) com class, e depois vou fazer um teste pra ver no que da.
abraço.
Tipo, vocês estão retirando algumas coisas que se vier de uma textarea vai quebrar a formatação de algum usuário.
Se colocar apenas uma barra invertida na frente desses caracteres já não inibe o slqinjection?
>
Tipo, vocês estão retirando algumas coisas que se vier de uma textarea vai quebrar a formatação de algum usuário.
Se colocar apenas uma barra invertida na frente desses caracteres já não inibe o slqinjection?
na verdade esse script serviria para limpar os dados de um textfield de login. em um textarea certamente surgirão alguns poréns. a contra-barra antes dos caracteres não resolve muito, a não ser na frente de aspas simples. eu diria não resolve muito, por que ai não ocorre o controle de ataques xss csrf, etc...
A retirada do '=' em particular não acarreta problemas, assim como a existência de outras expressões tbm não tem muita influência, como por exemplo o '@'.
concordo com Andre Cocuroci
nao há necessidade em limitar muitas expressões
basta evitar os escapes pois são eles que permitem as injeções
o importante é "evitar que a agulha penetre na veia". conseguindo isso não precisa se preocupar com o "conteúdo da seringa".
uma dica para evitar injeções é filtrar caracteres no formato ASC
Concordo também....
Eu tive esse problema, to mandando um site pessoal, onte vou falar de programacao e vou deixar os visitantes enviarem seus códigos,
eis o problema, como deixar que mandem códigos sobre PHP, MySQL, JavaScript (Futuramente + linguagens) sem sofre com Injection e sem destruir o código enviado?
>
<?
function sqlinj($string,$substituicao = true) {
if ($substituicao) {
$string = strip_tags($string);
$string = preg_replace("'(SELECT|FROM|WHERE|INSERT|UPDATE|DELETE|DROP|DATABASE|USE)'","",$string);
}
$string = htmlspecialchars($string,ENT_QUOTES);
return $string;
}
?>
é login? $login = sqlinj($login);
é código? $codigo = sqlinj($codigo,false);
* O uso do htmlspecialchars junto ao addslashes é pq ainda nao estudei a fundo vulnerabilidades de um ou de outro
Ate a próxima =D
eis o problema, como deixar que mandem códigos sobre PHP, MySQL, JavaScript (Futuramente + linguagens) sem sofre com Injection e sem destruir o código enviado?
basta escapar as aspas..
exemplo
<?php
function addslashes_deep( $value )
{
$value = is_array( $value ) ?
array_map( 'addslashes_deep', $value ) :
addslashes( $value );
return $value;
}
function arrJoin( $v ){
return implode( chr(13), $v );
}
function onlyNumber( $string ){
$rs = '';
if( $string != '' && !is_array( $string ) ){
$string = mb_convert_kana( $string, 'n' ); // [http://php.net/mb_convert_kana](http://php.net/mb_convert_kana)
$allowed = "/[^0-9]/i";
$rs = preg_replace( $allowed, '', $str );
}
return $rs;
}
function sqlClear( $rs, $opt ){
switch( $opt ){
case 'string';
$rs = "'" . addslashes_deep( trim( $rs ) ) . "'";
break;
case 'number';
$rs = onlyNumber();
break;
}
return $rs;
}
$test1 = "teste";
$test2 = "'; DROP table;--"; // simulando uma injeção...
$values[] = sqlClear( $test1, 'string' );
$values[] = "," . sqlClear( $test2, 'string' );
$fields[] = "filed1";
$fields[] = ", field2";
$sql[] = "INSERT INTO";
$sql[] = " table ";
$sql[] = " ( " . arrJoin( $fields ) . " ) ";
$sql[] = " VALUES ";
$sql[] = " ( " . arrJoin( $values ) . " );";
echo arrJoin( $sql );
?>utilizo essa pessoal:
function tratadados()
{
//pega os argumentos
$argumentos = func_get_args();
//pega o numero de argumentos inseridos
$quantidade_argumentos = func_num_args();
for($cont=0;$cont<$quantidade_argumentos;$cont++)
{
$resultado[$argumentos[$cont]] = trim($_POST[$argumentos[$cont]]);
$resultado[$argumentos[$cont]] = strip_tags($resultado[$argumentos[$cont]]);
$resultado[$argumentos[$cont]] = addslashes($resultado[$argumentos[$cont]]);
}
return $resultado;
}formulario
<form>
<input type='text' name='nome'>
<input type='text' name='sobrenome'>
<input type='text' name='endereco'>
</form>
poderia chamar com diferentes argumentos:
tratadados(nome,sobrenome,endereco);
tratadados(nome);
ela volta um vetor com nome das variaveis inseridas:
$dados = tratadados(nome,sobrenome,endereco);
$dados['nome']
$dados['sobrenome']
$dados['endereco']
outra coisa tb, e verificar sempre todos os dados de formulario, mesmo os fixos, como <option> <select>, e se forem valores numericos pode-se economizar tempo verificando simplesmente se ele é numerio com floatvar(), no caso:
$var = '123.321 php';
$var = floatval($var);
echo $var;Diogo Lana resumindo sua função irá tratar mas ira retornar \\\ caso a pessoa digite exemplo ' ou " ou seja vai inserir no banco de dados, creio que juntando sua função mas outra que faça a detecção e informe que aquele campo tem caracteres creio que seja ideal, teria como você adaptar na sua função para poder limitar caracteres exemplo -- não pode - pode, * não pode, e por ai vai assim a pessoa alem de tratar o erro ainda bloquiaria os que não quer ao inves de ter que fazer ao contrario de dizer quais não quer.
vlw.
>
Diogo Lana resumindo sua função irá tratar mas ira retornar \\\ caso a pessoa digite exemplo ' ou " ou seja vai inserir no banco de dados, creio que juntando sua função mas outra que faça a detecção e informe que aquele campo tem caracteres creio que seja ideal, teria como você adaptar na sua função para poder limitar caracteres exemplo -- não pode - pode, * não pode, e por ai vai assim a pessoa alem de tratar o erro ainda bloquiaria os que não quer ao inves de ter que fazer ao contrario de dizer quais não quer.
vlw.
mas eu acho que o intuito nao é esse .... limitar caracteres que possam ser usados por uma pessoa normal sem segundas intençoes não e bom, ja que você estaria modificando os dados enviados pela mesma...
eu prefiro transformar, (na verdade eu acho que é essa a atitude certa) caracteres possivelmente perigosos em inofensivos, sem modificar/distorcer qq dados ...
mas imagina o pessoal cadastrando
* \\\\ ' & ¨% $ # ( ) { [ } ] / ^~`´º
fica meio esquezito fora muitas outras coisas, por isso acho o seguinte melhor metodo de evitar injeções e criar funções tradando o que pode ou o que não pode exemplo.
Vamos supor um campo de usuário:
function checa($string)
{
$string = preg_match("/^[0-9A-z]*$/i", $string);
return $string;
}>
mas imagina o pessoal cadastrando
* \\\\ ' & ¨% $ # ( ) { [ } ] / ^~`´º
fica meio esquezito fora muitas outras coisas, por isso acho o seguinte melhor metodo de evitar injeções e criar funções tradando o que pode ou o que não pode exemplo.
Vamos supor um campo de usuário:
isso é outra questão
é tratamente individual pra cada campo
o ideal é faze um geral anti-inject, para todos, e um personalizado para cada campo.
obviamente que a maioria das vezes, muitos campos possuirão regras semelhantes.
Justamente para geral você pode usar somente addslashes que já resolve depois você trata com outras funções e para ficar melhor pode criar arquivos de logs que informa erros obtidos ou tentavivas do mesmo ao seu banco de dados.
>
>
mas imagina o pessoal cadastrando
* \\\\ ' & ¨% $ # ( ) { [ } ] / ^~`´º
fica meio esquezito fora muitas outras coisas, por isso acho o seguinte melhor metodo de evitar injeções e criar funções tradando o que pode ou o que não pode exemplo.
Vamos supor um campo de usuário:
isso é outra questão
é tratamente individual pra cada campo
o ideal é faze um geral anti-inject, para todos, e um personalizado para cada campo.
obviamente que a maioria das vezes, muitos campos possuirão regras semelhantes.
tb acho ...fora que um usuario realmente interessado em participar de uma comunidade nao iria colocar nunca um apelido assim ...
você tratar os dados obrigando o usuario a usar uma quantidade limitada de caracteres e uma coisa, simplesmente corromper dados pq aquele caractere especifico e potencialmente perigoso acho errado .... mas isso e minha opniao né
Sim cada um tem sua opinião mas eu não quero em meus cadastros com nome de usuários exemplo: ///'Delete ou Chupauqe%$#@
Alguns exemplos bobos mas da para entender, mas num consenso creio que a melhor forma de proteção seria a basica e simples tratar as variaveis com o que pode ou com que não pode.
O pessoal que estava postando no inicio poderia voltar e postar comentarios sobre que acha dos CODE do pessoal assim fluindo cada vez mas o assunto e melhorando os Codigos.
flw abraço a todos deus abençoe.
Sim cada um tem sua opinião mas eu não quero em meus cadastros com nome de usuários exemplo: ///'Delete ou Chupauqe%$#@
essa questão já não é relacionada a segurança, e sim a tratamento de dados
Isso é uma coisa complicada mesmo.
Estou desenvolvendo um fórum, e na textarea de criação de tópicos pode ser digitada qualquer coisa, mas se eu limitar muito, posso destruir a postagem do usuário.
Acho que o ideal seria criar uma lista de substituição.
Na hora de gravar no banco ele troca coisas perigosas por outros caracteres, e na hora de exibir no site, desfaz a troca.
Não sei o quanto isso seria viável em termos de segurança e performance.
Comentários?
=D