Pessoal, vamos falar um pouco de segurança em aplicações WEB? Muito se fala sobre SQL Injection, que é a injeção de comandos SQL numa aplicação WEB através de falhas de segurança. A Injeção desses códigos podem permitir desde a simples mudança de um valor no banco de dados até a exclusão de todas as tabelas do seu banco de dados.
Assim como SQL Injection, há outros tipos comuns de Injections: PHP Injection, Email Injection, Form Injection, etc.
Hoje falarei de Form Injection!
Percebo que pouca gente se liga nesse tipo de ataque! Vamos em frente e você mesmo me dirá se estou certo ou não.
<form methos="post" action="cadastra.php">
<fieldset>
<legend>Um formulário de Exemplo</legend>
<input type="hidden" id="cod" name="cod" value="12" />
<label for="nome">Nome:</label><br />
<input type="text" id="nome" name="nome" maxlength="30" /><br />
<label for="senha">Senha:</label><br />
<input type="password" id="senha" name="senha" maxlength="10" /><br />
<label for="sexo">Sexo:</label><br />
<select id="sexo" name="sexo">
<option value="M">Masculino</option>
<option value="F">Feminino</option>
</select><br />
<input type="submit" id="enviar" name="enviar" value="Enviar' />
</fieldset>
</form>Como podem ver, é um formulário bem simples e ingênuo, mas dependendo da sua programação em PHP, pode trazer algumas inconsistências no seu banco de dados, por exemplo.
Suponhamos que esse formulário esteja hospedado em www.meusite.com.br e que o meu código PHP na página cadastra.php está assim:
<?php
if ( $_SERVER["REQUEST_METHOD"] == "POST" ) {
foreach ( $_POST as $c => $v ) {
$$c = $v;
}
if ( empty( $nome ) || empty( $senha ) ) {
die("Algum campo está em branco.");
}
$sql = "insert into tabela values ($cod,'$nome', '$senha', '$sexo')";
//Faz a conexão com o banco de dados
//Executa a query $sql
}
?>Como podem ver, verificamos se os campos "nome" e "senha" estão vazios (em branco) e, caso estejam, paramos a execução do nosso script exibindo uma mensagem de erro. Caso não estejam em branco, gravamos os dados no banco de dados.
Caso você nunca tenha ouvido falar em Form Injection, deve estar se perguntando: "E tem alguma coisa errada?".
A priori, o seu script funcionará bem porque a grande maioria dos usuários são leigos e/ou não estão interessados em causar nenhum tipo de dano.
Mas vamos supor que o usuário malicioso salve o código HTML do formulário na máquina local (máquina do usuário) e faça as seguintes alterações:
<form methos="post" action="http://www.meusite.com.br/cadastra.php">
<fieldset>
<legend>Um formulário de Exemplo</legend>
<input type="hidden" id="cod" name="cod" value="2" />
<label for="nome">Nome:</label><br />
<input type="text" id="nome" name="nome" maxlength="50" /><br />
<label for="senha">Senha:</label><br />
<input type="password" id="senha" name="senha" maxlength="50" /><br />
<label for="sexo">Sexo:</label><br />
<select id="sexo' name='sexo">
<option value="Zuei o seu site">Zuei o seu site</option>
</select><br />
<input type="submit" id="enviar" name="enviar" value="Enviar" />
</fieldset>
</form>Está atento? Não? Então vamos às alterações feitas:
O que aconteceria se o usuário malicioso executasse essa página em seu browser e a submetesse? Alguns erros! No mínimo.
Nesse caso, só aconteceram erros.
Mas e se o malicioso trocasse o value do option de "Zuei o seu site" para "G" e colocasse strings de 10 caracteres nos campos nome e senha?
Ao invés de inserir um registro com código 12, seria inserido com código 2 e pior: com sexo "G".
Essas são situações simples e que acarretariam poucos danos. Mas essa falha, se bem explorada, pode causar sérios problemas de consistência em sua base de dados.
Vamos à solução?
Na verdade, essa é a maneira como EU faço, mas há outras formas de fazer, obviamente.
<?php
if ( $_SERVER["REQUEST_METHOD"] == "POST" ) {
foreach ( $_POST as $c => $v ) {
$$c = $v;
if ( empty( $v ) ) {
die( "O campo $c está em branco." );
}
}
$nome = substr($nome, 0, 30);
$senha = substr($senha, 0, 10);
if ( $sexo != "M" && $sexo != "F" ) {
die( "Campo sexo com valor inapropriado." );
}
//Faz a validação do campo $cod
$sql = "insert into tabela values ($cod, '$nome', '$senha', '$sexo')";
//Faz a conexão com o banco de dados
//Executa a query $sql
}
?>Em suma, para se ver livre do Form Injection assim como outros tipos de Injection, a solução é relativamente simples: basta o desenvolvedor se preocupar em validar todos os dados em que há interação com o usuário!!
Assim, uma boa validação server-side (feita no lado do servidor, ou seja, através de linguagem processada no servidor), resolve a maior parte dos problemas, inclusive esse.
Espero que tenham gostado e que tenham comentários a fazer!
Abraços!
André Mauricio Garcia
...mas de qualquer forma a solução ainda não está nem perto de resolver o problema mais grave que percebi no formulário acima: o uso de campo hidden para trabalhar o id (ou cod) na tabela.
Existem empresas gigantes que tiveram problemas com formulários assim.
É uma prática que deve, no mínimo, ser bem estudada, validar o campo antes e após o envio do formulário e uma solução viável.
A validação pode ser feita por sessão ou pelo método de sua preferência, mas fica o gancho para uma próxima matéria. O assunto é muito interessante e o mais impressionante é que não tem tanta gente que se preocupa com isso, deixando as aplicações vulneráveis a ataques simples.
Parabéns pelo assunto
Nil Tojal
Legal a materia..so não entendi algumas coisas..exemplo...
o cara o pega o codigo do form na sua maquina local.. altera o que quiser tudo bem.. mas como ele consegue depois executar esse codigo no meu site remotamente... ou seja como ele consegue colocar esse codigo no meu site ... se ele não tem senha do ftp ou que seja....
a pergunta pode se banal para alguns ..mas é a minha duvida..abraçosss
Gustavo Andrade
Nil, é quando ele altera o "action" do form de cadastra.php para http://www.meusite.com.br/cadastra.php, obtendo o caminho completo, basta executar o arquivo localmente... tmferreira, muito interessante o artigo, mais uma forma de evitar injeção de comando
Charles Souza
ressucitando o artigo.
thiago está muito seu artigo.
mas voce poderia escrever outro artigo sobre injection, porque esse assunto eh muito importante, apesar de haver muito material na net, nem todos são claros assim, flw
Thiago Ferreira
Valeu, Charles! E sobre injection de que você está falando?
2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.