Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Dyego

Segurança Anti Inject

Recommended Posts

Olá pessoal, estou precisando de uma ajuda com ANTI INJECT,

utilizo banco de dados MSSQL, faço conexão com 6 DBs - 5 MSSQL e 1 MYSQL, no mesmo projeto,

 

Tenho um sistema de proteção para ANTI INJECT mas queria saber a sugestão de você se é seguro

e se posso melhorar de alguma forma.

 

Seria proteção contra INJECT e Execução de algum codigo indevido.

 

veja o meu código

 

<?php
function xw_sanitycheck($str){
   if(strpos(str_replace("''",""," $str"),"'")!=false)
       return str_replace("'", "''", $str);
   else
       return $str;
}

function secure($str){
   // Case of an array
   if (is_array($str)) {
       foreach($str AS $id => $value) {
           $str[$id] = secure($value);
       }
   }
   else
       $str = xw_sanitycheck($str);

   return $str;
}

// Get Filter
$xweb_AI    = array_keys($_GET);
$i=0;
while($i<count($xweb_AI)) {
   $_GET[$xweb_AI[$i]]=secure($_GET[$xweb_AI[$i]]);
   $i++;
}
unset($xweb_AI);

// Request Filter
$xweb_AI    = array_keys($_REQUEST);
$i=0;
while($i<count($xweb_AI)) {
   $_REQUEST[$xweb_AI[$i]]=secure($_REQUEST[$xweb_AI[$i]]);
   $i++;
}
unset($xweb_AI);

// Post Filter
$xweb_AI    = array_keys($_POST);
$i=0;
while($i<count($xweb_AI)) {
   $_POST[$xweb_AI[$i]]=secure($_POST[$xweb_AI[$i]]);
   $i++;
}

// Cookie Filter (do we have a login system?)
$xweb_AI    = array_keys($_COOKIE);
$i=0;
while($i<count($xweb_AI)) {
   $_COOKIE[$xweb_AI[$i]]=secure($_COOKIE[$xweb_AI[$i]]);
   $i++;
}

?>

 

Um amigo me falou para adicionar isso na function xw_sanitycheck

$string_b = addcslashes($string_i, "\x00\n\r\'\x1a\x3c\x3e\x25");

 

Mas no caso o MSSQL não interpreta o \ como escape.

Alguem pode me ajudar a aprimorar essa segurança.

 

Desde já obrigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Nunca trabalher com MSSQL, mas o MySQL não precisa dessa coisarada toda aí não, existe uma função chamada mysqli_real_escape_string da extensão mysqli que resolve o problema de injection. Se der uma pesquisada por aí, talvez encontre uma equivalente para o MSSQL. A sua dúvida não tem muito a ver com PHP, eu acho.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pela dica, ja procurei, não tem nenhuma função mssql anti inject nativa no php ...

claro que tem haver com PHP pois a proteção tem que ser feita por meio do sistema ...

 

por exemplo no login, no cadastro ... e por ai vai .... no envio de forms ....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Claro que isso depende muito do caso.

Por exemplo, aqui mostro que um ataque de injeção de SQL pode ser feito sem nenhuma aspa na URL, e assim é impossível bloquear via mysql_real_escape_string() ou addslashes().

Naquele caso (uma página de notícias) eu apresentei uma solução e o Matias Rezende apresentou outra. Nenhuma delas inclui usar uma única função.

Geralmente, quando eu pego um sistema grande e pronto para fazer alguma manutenção, e vejo que ele está muito vulnerável, procuro um arquivo que é incluído em todos os outros arquivos (geralmente o arquivo da conexão ao MySQL) e bloqueio comandos comuns aos ataques de SQLi e BlindSQLi:

$url = $_SERVER['QUERY_STRING'];
$bloqueio = Array("union", "order", "substr", "concat", "information_schema", "from", "UNION", "ORDER", "SUBSTR", "CONCAT", "INFORMATION_SCHEMA", "FROM");
$url = str_replace($bloqueio, "%SQLI%", $url);
if(strpos($bloqueio, "%SQLI%")) {
 die('<script> alert("Opa, amigo! SQLi aqui não."); location.href="index.php"; </script>');
}

 

Nunca trabalher com MSSQL, mas o MySQL não precisa dessa coisarada toda aí não

[2]

Compartilhar este post


Link para o post
Compartilhar em outros sites

Geralmente, quando eu pego um sistema grande e pronto para fazer alguma manutenção, e vejo que ele está muito vulnerável, procuro um arquivo que é incluído em todos os outros arquivos (geralmente o arquivo da conexão ao MySQL) e bloqueio comandos comuns aos ataques de SQLi e BlindSQLi:

$url = $_SERVER['QUERY_STRING'];
$bloqueio = Array("union", "order", "substr", "concat", "information_schema", "from", "UNION", "ORDER", "SUBSTR", "CONCAT", "INFORMATION_SCHEMA", "FROM");
$url = str_replace($bloqueio, "%SQLI%", $url);
if(strpos($bloqueio, "%SQLI%")) {
 die('<script> alert("Opa, amigo! SQLi aqui não."); location.href="index.php"; </script>');
}

Isso não resolve nem 1 terço do problema, primeiro que uma pessoa pode ter uma keyword SQL em seu nome, pode enviar uma palavra inglês como 'union' , 'select ' .. 'from' .. em uma caixa de descrição ou texto, que é enviado para seu site, e vou te dizer a mesma coisa que digo para vários que questionam isto aqui no fórum, REMOVER KEYWORDS SQL DO TEXTO ENVIADO não resolve o problema.

 

O escape_string do MySQL / MySQLi só resolve um dos problemas também, aspas são as mais fáceis de resolver ..

<?php	
mysql_connect( '127.0.0.1' , 'root' , '?' ) ;
echo mysql_real_escape_string( "SELECT * FROM `tabela`'; ..." );

 

Saída:

SELECT * FROM `tabela`\'; ...

 

Agora .. por outro lado ..

mysql> select hex( "';DROP TABLE `tabela`" );
+--------------------------------------------+
| hex( "';DROP TABLE `tabela`" )             |
+--------------------------------------------+
| 273B44524F50205441424C452060746162656C6160 |
+--------------------------------------------+
1 row in set (0.00 sec)


mysql> select 0x273B44524F50205441424C452060746162656C6160;
+----------------------------------------------+
| 0x273B44524F50205441424C452060746162656C6160 |
+----------------------------------------------+
| ';DROP TABLE `tabela`                        |
+----------------------------------------------+
1 row in set (0.00 sec)

mysql>

 

Como você evitaria isso ? o escape não vai ter efeito nenhum

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, coisas do tipo:

SELECT FROM `teste` WHERE nome = '' OR DROP TABLE `teste`;
SELECT (DROP TABLE `teste`) FROM `teste` WHERE nome = ''

Não são sentenças SQL válidas, pelo menos, não na implementação do MySQL.

 

Quanto a isso, não tem muito o que se preocupar. Pelo que eu me lembro, o MSSQL também não permite múltiplas queries, como o MySQL, o que dá uma grande ajuda na questão da segurança.

Compartilhar este post


Link para o post
Compartilhar em outros sites

São sim ..

mysql> use db;
Database changed

mysql> show tables;
Empty set (0.00 sec)

mysql> create table teste(
   ->        id integer
   -> ) engine = myisam;
Query OK, 0 rows affected (0.09 sec)

mysql> show tables;
+--------------+
| Tables_in_db |
+--------------+
| teste        |
+--------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM `db`.`teste` WHERE `id` = 0; DROP TABLE db.teste; --
Empty set (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
Empty set (0.00 sec)

mysql>

Compartilhar este post


Link para o post
Compartilhar em outros sites

SELECT * FROM `db`.`teste` WHERE `id` = 0; DROP TABLE db.teste;

Uma query assim você consegue rodar no MySQL GUITools ou no PHPMyAdmin, mas não consegue executá-la usando as funções mysql(i)_*, pois não há suporte a queries múltiplas.

 

Como você evitaria isso ? o escape não vai ter efeito nenhum

Vou dizer como eu faço:

 

Bom, normalmente, os parâmetros que eu mais uso são ID's dos registros da tabela. Como um ID é inteiro, é só fazer o casting:

$id = (int) $_GET['id'];

Quando são strings, normalmente é alguma função de busca ou algo do tipo, aí sim caberia ao PHP fazer um pré-processamento dos dados.

Para entradas de formulários, sempre há uma validação, quando se trata da parte pública do site/sitema.

Eu nunca tive problemas relacionados a isso, em 4 anos de desenvolvimento...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa pessoal,

 

o MSSQL roda 2 querys juntos sim, só colocando um "GO" entre elas.

 

em cada POST, GET e outros eu faço uma verificação de caracteres ... por exemplo aceitar apenas letras ou numeros,

mas no caso em um form de comentarios, não da pra limitar muita coisa ....

 

if((eregi("[^0-9a-zA-Z_]", $s))) {
// Tem caracteres não autorizados
} else {
// Continua
}

 

Vou dar uma olhada nessa pagina ...

Compartilhar este post


Link para o post
Compartilhar em outros sites

uma dica, é que as "injeções" podem provir de qualquer canto.

 

por exemplo, de um cookie que conhenha dados para formar uma query SQL, como o login

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.