PHP e SQL Injection

07/11/06

Estava explicando para um amigo meu porque não se deve interpolar uma variável direto no SQL. O grande problema é que ao fazer desta maneira, seu sistema fica suscetível a SQL Injection.

Imagine que você faça algo como abaixo.

<?php
$query = "SELECT name, email, password FROM table WHERE field='".$_GET['field']."' LIMIT 1";
?>

Se alguém passar no parâmetro algo como ' OR 1=1 #, seu banco ficaria totalmente exposto, pois a string final seria modificada com uma condição que será sempre satisfeita.

SELECT name, email, password FROM table WHERE field = '' OR 1=1 #' LIMIT 1

Parabéns! Alguém acabou de pegar todos os registros de sua tabela. Para evitar esse tipo de ataque, é aconselhável usar a função mysql_real_escape_string. Ela faz o devido escape de caracteres potencialmente inseguros. A desvantagem é que você tem que fazer isso para cada um dos parâmetros que você vai passar, o que pode se tornar um pouco massante.

Então, passei para ele uma função que eu usava há algum tempo atrás.

<?php
/**
 * @param string $query
 * @param mixed $arg1, $arg2...$argN 
 */
$QUERY = "";
function query($query)
{
    global $QUERY;
    
    $args = func_get_args();
    $query = array_shift($args);
    
    foreach ($args as $key => $arg) {
        if (is_string($arg)) {
            $args[$key] = mysql_real_escape_string($arg);
        }
    }
    
    array_unshift($args, $query);
    $query = call_user_func_array('sprintf', $args);
    $QUERY = $query;
    
    return mysql_query($query);
}
?>

Use a função acima da seguinte maneira:

<?php
$query = "SELECT name, email, password FROM table WHERE field='%s' LIMIT 1";
$resource = query($query, $_GET['field']);
 
while ($row = mysql_fetch_object($resource)) {
    printf('<strong>%s:</strong> %s<br/>', $row->name, $row->email);
}
?>

Você pode passar quantos parâmetros precisar, seguindo as regras da função sprintf.

<?php
$query = "INSERT INTO table (amount, age, name) VALUES (%.2f, %d, '%s')";
$resource = query($query, 150, 27, 'Nando Vieira');
?>

Uma outra vantagem de usar a função acima é que se você esquecer de passar algum parâmetro que estava esperando receber, um erro será exibido. E de quebra você ganha uma variável global $QUERY com a última instrução executada.

Aprendendo Ruby

20/10/06

Se você sempre teve vontade de aprender Ruby, por causa do Rails, mas ficou com preguiça de aprender mais uma linguagem, sua desculpa esfarrapada acabou! Dá uma olhada neste tutorial, muito bem feito por sinal, e te garanto que vai ficar fazendo os exercícios até acabarem. Te disse que os tutoriais são feitos todos através do browser? Então, vai lá!

Firefox vs Flash 9

19/10/06

Bom, todo mundo está sabendo que saiu a versão beta do Flash 9. Instalei, para ver como está a coisa mas já voltei para a versão 7. Isso porque toda vez que eu tentava ver um vídeo no youtube, o player travava por volta dos 30 segundos e ficava sem som. Tentei acessar um outro site e o plugin literalmente travou o Firefox. Viver sem Flash 9 eu consigo, mas sem youbube…

Por isso, vou esperar sair a versão final! Fica a dica caso seu browser comece a travar muito após instalar o novo plugin.