Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Hoje estou com o seguinte problema, usei o programa NESSUS para análise de injection no meu site.
E retornou o possível invasão crítica no site, utilizando o Link abaixo, alguma ajuda, pois a tratativa já estou fazendo via AntiSQL Injection. Abaixo segue a situação real do sistema.
Link:
http://www.nomedosite.com.br/premios/150/?'+convert(int,convert(varchar,0x7b5d))+'=1
.htaccess
RewriteRule ^premios/([0-9-]+)/([1-3])?$ index.php?p=premios&id_premio=$1&colocacao=$2
Saída Executar = TENTATIVA DE INVASÃO VIA BROWSER:
Mensagem de Erro: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corres ponds to your MySQL server version for the right syntax to use near '' a t line 1
premios.php
<?php
$id_premio= antiSQL($_GET['id_premio']);
$colocacao = antiSQL($_GET['colocacao']);
$echo "Depois continua o código normal...";
?>
Função antiSQL:
<?php
if(!function_exists("antiSQL")) {
function antiSQL($campo, $adicionaBarras = false) {
// remove palavras que contenham sintaxe sql
$campo = preg_replace("/(from|alter table|select|insert|delete|update|were|drop table|show tables|#|\*|--|\\\\)/i","Anti Sql-Injection - bjus Mãe !",$campo);
$campo = trim($campo);//limpa espaços vazio
$campo = strip_tags($campo);//tira tags html e php
if($adicionaBarras || !get_magic_quotes_gpc())
$campo = addslashes($campo);
return $campo;
}
}
?>Utilize prepared statements e seja feliz.
Amigo, tem como dar um exemplo? sou meio novato ?
A função que uso para selecionar o registro e a listar a tabela com while está logo abaixo:
'
function selecionar_registro_id($tabela, $campoTabela, $campo_id_chave) {
$pdo = conectarBanco();
try {
$listar = $pdo->prepare("SELECT * FROM " . $tabela . " WHERE " . $campoTabela . " = :id");
$listar->bindValue(":id", $campo_id_chave);
$listar->execute();
if ($listar->rowCount() > 0) :
$dados = $listar->fetch(PDO::FETCH_ASSOC);
return $dados;
else :
return false;
endif;
} catch (PDOException $error) {
echo "<h4>";
echo "Mensagem de Erro: " . $error->getMessage();
echo "</h4>";
}
}
E a função para Listar a Tabela é essa:
function listar_tabela($tabela, $parametros = null) {
$pdo = conectarBanco();
try {
if (is_null($parametros)) :
$listar = $pdo->prepare("SELECT * FROM " . $tabela);
else :
$listar = $pdo->prepare("SELECT * FROM " . $tabela . $parametros);
endif;
$listar->execute();
if ($listar->rowCount() > 0) :
$dados = $listar->fetchAll(PDO::FETCH_ASSOC);
return $dados;
else :
return false;
endif;
} catch (PDOException $error) {
echo "<h4>";
echo "Mensagem de Erro: " . $error->getMessage();
echo "</h4>";
}
}para sql injection use a função do proprio mysql mysql_real_escape_string()
A mysql_ já é obsoleta e reproduz um E_DEPRECATED no PHP 5.5 e será removida no futuro. Portanto, use PDO.
http://www.php.net/manual/pt_BR/pdo.prepared-statements.php
Jamais use esta função que você mostrou (antiSQL).
É uma solução que pode piorar a segurança e a usabilidade do seu sistema: imagine que alguém se cadastrou com uma senha/email que contenha uma palavra sql. E aí? como fica o usuário? Ele vai ter que digitar "Anti Sql-Injection - bjus Mãe !" :lol:?
Prepared Statements FTW!
Olá Pessoal,
Eu revisei a própria função PDO conforme me solicitado, porém ainda apresenta o mesmo erro de invasão, alguma ajuda?
function listar_tabela($tabela, $parametros = null) {
$pdo = conectarBanco();
try {
if (is_null($parametros)) :
$listar = $pdo->prepare("SELECT * FROM " . $tabela);
else :
$listar = $pdo->prepare("SELECT * FROM " . $tabela . $parametros);
endif;
$listar->execute();
if ($listar->rowCount() > 0) :
$dados = $listar->fetchAll(PDO::FETCH_ASSOC);
return $dados;
else :
return false;
endif;
} catch (PDOException $error) {
echo "<h4>";
echo "Mensagem de Erro: " . $error->getMessage();
echo "</h4>";
}
}
Chamando a Função:
$listagem = listar_tabela("clientes", " WHERE situacao = 0 OR situacao = 2 OR situacao = 5 ORDER BY data_cadastro DESC");
Usando PDO, ainda assim me retorna a tentativa de invasão mencionada no início deste post. Me ajudem, estou ficando birutinha...rs Abraços...
Você não está usando prepared statements.
Leia => http://php.net/manual/en/pdo.prepared-statements.php
Você não tem que se prevenir contra tentativas de invasão. Você tem que se prevenir contra os sucessos. Apesar do alerta informado, não houve sucesso. O PHP emitiu uma mensagem de erro e o checador automatizado de falhas de segurança assumiu isso como uma brecha. Sabe-se lá o que ele esperava como retorno.
Veja a função já otimizei, retorna o seguinte ERRO.
Mensagem de Erro: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''clientes' ' WHERE situacao = 0 OR situacao = 2 OR situacao = 5 ORDER BY data_cadastro' at line 1
Chamando a Função:
>
$listagem = listar_tabela("clientes", " WHERE situacao = 0 OR situacao = 2 OR situacao = 5 ORDER BY data_cadastro DESC");
Função:
function listar_tabela($tabela, $parametros = null) {
$pdo = conectarBanco();
try {
if (is_null($parametros)) :
$listar = $pdo->prepare("SELECT * FROM ?");
$listar-> bindValue(1, $tabela);
else :
$listar = $pdo->prepare("SELECT * FROM ? ?");
$listar-> bindValue(1, $tabela);
$listar-> bindValue(2, $parametros);
endif;
$listar->execute();
if ($listar->rowCount() > 0) :
$dados = $listar->fetchAll(PDO::FETCH_ASSOC);
return $dados;
else :
return false;
endif;
} catch (PDOException $error) {
echo "<h4>";
echo "Mensagem de Erro: " . $error->getMessage();
echo "</h4>";
}
}Bind é só para valores. Não para tabelas.
select campo1, campo2, campo3 from tabela where campoa = ? and campob > ? and campo1 != ?
Exemplo bem simples:
BasePdo.php
/**
* Classe base de PDO
*
*/
abstract class BasePdo {
// conexão com o banco
static private $pdo = null;
// para extender/usar nas subclasses
protected $tablename;
// ultimo statement gerado
protected $stmt;
// recupera a conexão com o banco
static protected function getConnection()
{
if(is_null(self::$pdo)){
try {
self::$pdo = new PDO('mysql:dbname=escola;port=3306;host=127.0.0.1','root','');
} catch(PDOException $ex) {
// log da operação
throw $ex;
}
}
return self::$pdo;
}
// verifica se o nome da tabela está definido
// e não sendo acessado da classe base
protected function validateTablenameAndClass()
{
if($this->tablename == ''){
throw new Exception('Invalid tablename (it\'s empty)');
}
if(get_class($this) == 'BasePdo'){
throw new Exception('You MUST extend this class');
}
}
// recupera todos os itens, sem filtro
public function getAllItems($type = PDO::FETCH_ASSOC)
{
$this->validateTablenameAndClass();
if(empty($this->tablename)){
}
$pdo = self::getConnection();
$sql = 'SELECT * FROM ' . $this->tablename;
$this->stmt = $pdo->prepare($sql);
$this->stmt->execute();
return $this->stmt->fetchAll($type);
}
// faz filtros pelo campo
public function find(array $filters = array(), $autoFetchAll = true, $type = PDO::FETCH_ASSOC)
{
$sql = 'SELECT * FROM '.$this->tablename;
$where = array();
$params = array();
foreach($filters as $column => $value){
if(is_null($value)){
$where[] = $column . ' IS NULL';
} else {
$where[] = $column . ' = ?';
$params[] = $value;
}
}
if(!empty($where)){
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$this->stmt = self::getConnection()->prepare($sql);
if(!$this->stmt->execute($params)){
$error = $this->stmt->errorInfo();
throw new Exception($error[2], $error[1]);
}
if($autoFetchAll){
return $this->stmt->fetchAll($type);
}
return null;
}
}
Aluno.php
// extendo a classe base
class Aluno extends BasePdo {
protected $tablename = 'aluno';
}include 'BasePdo.php';
include 'Aluno.php';
$aluno = new Aluno();
$result = $aluno->find(array(
'nome_completo'=>'hugo'
));
print_r($result);
Utilize prepared statements e seja feliz.