Entendendo SQL Injection

Este artigo tem como objetivo explorar metodicamente a vulnerabilidade SQL Injection, demonstrando como ela ocorre e qual a causa dessa vulnerabilidade ser tão recorrente até os dias atuais.

[ Hits: 2.684 ]

Por: Alan Lucena em 04/02/2024


Introdução



A segurança da informação é uma preocupação central no mundo da tecnologia e é, muitas vezes, um tópico negligenciado em sistemas de gerenciamento de banco de dados e aplicações web. Um dos ataques mais comuns e perigosos que podem comprometer a segurança de um sistema é a injeção de SQL. Neste artigo, exploraremos em profundidade o que é a injeção de SQL, como ela funciona e, mais importante, por que ela ocorre, tomando como exemplo um código PHP vulnerável.

O que é SQL Injection?

A injeção de SQL é uma vulnerabilidade de segurança que ocorre quando um invasor manipula as entradas de um sistema para inserir comandos SQL maliciosos em consultas SQL legítimas. Isso pode permitir que o invasor execute comandos não autorizados em um banco de dados, comprometendo dados confidenciais, modificando ou excluindo registros e até mesmo assumindo o controle do sistema. Para entender como a injeção de SQL funciona, vamos analisar um exemplo prático em PHP.

Exemplo de Código Vulnerável em PHP + HTML Forms

<?php
ini_set("display_errors",1);

if($_SERVER['REQUEST_METHOD'] == 'POST') {
    $nc = mysqli_connect('localhost','root','1111');
    mysqli_select_db($nc,'injection');
    $usuario = $_POST['usuario'];
    $senha = $_POST['senha'];
    $sql = "SELECT * FROM login WHERE usuario = '$usuario' AND senha='$senha'";
    $query = mysqli_query($nc, $sql);

if(mysqli_num_rows($query)==1) {
    header("location:admin.html");
 }

 else {
    echo "Usuário ou senha inválidos";
    }
 }
?>



HTML Forms:


<!DOCTYPE html>
<html>
<head>
<title>SQL Injection</title>
</head>
<body>
<form action="index.php" method="POST">
<h1>Login - Vulnerável</h1><br>
Usuário:<br>
<input type="text"
name="usuario"<br><br>
Senha:<br>
<input type="text"
name="senha"<br><br>
<input type="submit" value="Login">
</Form>
</body>

Como Funciona a Injeção de SQL?

A vulnerabilidade neste código reside na forma como as variáveis $usuario e $senha são incorporadas diretamente na consulta SQL, sem validação adequada. Isso cria uma oportunidade para um atacante explorar a injeção de SQL. Se o invasor fornecer entradas maliciosas, como usuario com o valor ' OR '1'='1 e senha vazia, a consulta SQL resultante se parecerá com:

SELECT * FROM login WHERE usuario = '' OR '1'='1' AND senha='';

O `' OR '1'='1` é sempre verdadeiro, o que significa que o invasor pode enganar o sistema e obter acesso, mesmo sem a senha correta. Isso ocorre porque o código não está filtrando ou escapando as entradas do usuário adequadamente, permitindo que comandos SQL maliciosos sejam injetados na consulta.

Por que a Injeção de SQL Acontece?

A injeção de SQL ocorre principalmente devido a duas razões principais:

1. Falta de Validação de Entradas:

Os desenvolvedores muitas vezes não validam ou sanitizam adequadamente as entradas do usuário. Isso permite que os invasores insiram comandos SQL diretamente nas entradas do aplicativo.

2. Concatenação de Strings SQL:

A concatenação direta de entradas do usuário com strings SQL sem escapar ou usar parâmetros preparados cria uma abertura para a injeção de SQL.

Exemplo de tratamento parametrizado (PDO)

No exemplo abaixo, podemos observar que o código está utilizando uma nova forma de parametrização dos valores que são recebidos pelo usuário, validando o tipo de entrada/campo, antes de permitir o envio de strings do usuário para a aplicação


$sql = "SELECT * FROM login WHERE usuario=:usuario AND senha=:senha;"; $stmt = $conn->prepare( $sql ); $stmt-> bindParam( ':usuario', $usuario ); $stmt-> bindParam( ':senha', $senha ); $stmt->execute(); $result = $stmt->fetchAll();

if (count($result)) { header("location: admin2.php"); } else { throw new Error($stmt->errorInfo()); } } ?>

stmt = $conn->prepare( $sql );: Nesta linha, você está preparando uma consulta SQL para ser executada. $conn provavelmente é um objeto de conexão PDO que representa uma conexão com o banco de dados. $sql é a consulta SQL que você deseja preparar. Isso é feito para evitar a injeção de SQL, pois o PDO cuidará da sanitização e da execução segura da consulta.

stmt->bindParam( ':usuario', $usuario );: Aqui, você está vinculando um parâmetro nomeado :usuario na consulta SQL à variável $usuario. Isso significa que, quando a consulta for executada, o valor de $usuario será substituído no lugar de :usuario. Isso é útil para passar valores dinâmicos para a consulta sem se preocupar com a injeção de SQL.

stmt->bindParam( ':senha', $senha );: Da mesma forma, você está vinculando um parâmetro nomeado :senha à variável $senha. Isso permite que você substitua o valor de $senha na consulta.

stmt->execute();: Aqui, você está executando a consulta preparada. Isso significa que a consulta será enviada ao banco de dados com os valores de :usuario e :senha substituídos pelos valores em $usuario e $senha. A consulta será executada pelo banco de dados.

result = $stmt->fetchAll();: Depois que a consulta é executada com sucesso, você está pegando todas as linhas de resultados e armazenando-as em $result. Isso geralmente é usado quando você espera receber vários resultados da consulta, como ao buscar várias linhas de um banco de dados.

Em resumo, esse código PHP está preparando e executando uma consulta SQL segura usando PDO. Ele vincula os valores das variáveis $usuario e $senha à consulta, garantindo que eles sejam tratados de maneira segura e evitando vulnerabilidades de injeção de SQL.

Em tempo, PDO significa PHP Data Object e é uma extensão do PHP que fornece uma camada de abstração de acesso a banco de dados, nesse caso, SQL.

Conclusão

A injeção de SQL é uma ameaça séria à segurança de sistemas de banco de dados e aplicações web. Para evitá-la, os desenvolvedores devem validar e escapar adequadamente as entradas do usuário, além de utilizar parâmetros preparados em vez de concatenar strings SQL. Conscientização sobre segurança e práticas de desenvolvimento seguro são cruciais para proteger sistemas contra esse tipo de ataque. Aprender com exemplos como o apresentado neste artigo é um passo importante na direção certa para melhorar a segurança dos sistemas.



Referência Bibliográfica

LUCENA, Alan Rodrigo Ferreira de; LEITE, Renan Dias. Gestão de Vulnerabilidade em Aplicações WEB: Exploração de SQL Injection. 2019. Monografia (Graduação em Gestão da Tecnologia da Informação) - Tecnológico, Faculdade de Ciências de Timbaúba (FACET), Timbaúba, 2019. DOI 10.29327/41302367. Disponível em: Gestão de Vulnerabilidade em Aplicações WEB: Exploração de SQL Injection | TCC - Graduação | Even3 Publicações

   

Páginas do artigo
   1. Introdução
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Quebrando a criptografia RSA

Auditorias Teste de Invasão para Proteção de Redes Corporativas

PortSentry: Melhorando a segurança do seu Linux

Recuperando senhas de usuários

Chroot + Bind sem stress

  
Comentários
[1] Comentário enviado por maurixnovatrento em 07/02/2024 - 18:45h

Ótimo artigo.

______________________________________________________________________
Inscreva-se no meu Canal: https://www.youtube.com/@LinuxDicasPro
Repositório GitHub do Canal: https://github.com/LinuxDicasPro
Grupo do Telegram: https://t.me/LinuxDicasPro
Meu GitHub Pessoal: https://github.com/mxnt10


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts