Evitando Injeção de SQL no InterSystems IRIS: O Caso para Práticas de Consulta Seguras
A injeção de SQL continua sendo uma das vulnerabilidades mais críticas em aplicações que dependem de banco de dados, permitindo que atacantes manipulem consultas e potencialmente acessem ou comprometam dados sensíveis. No InterSystems IRIS, os desenvolvedores têm acesso tanto ao SQL Dinâmico quanto ao SQL Embutido, cada um com características distintas. Entender como usá-los de forma segura é essencial para prevenir a injeção de SQL.
O Problema: SQL Dinâmico e Injeção de SQL
O SQL Dinâmico constrói consultas como strings em tempo de execução. Embora isso ofereça flexibilidade, também cria uma vulnerabilidade se a entrada do usuário não for tratada corretamente. Por exemplo:
Set query = "SELECT Name, Age FROM Patients WHERE Age > "_age Set statement = ##class(%SQL.Statement).%New() Set status = statement.%Prepare(query)
Se a idade for fornecida pelo usuário, concatená-la diretamente na string da consulta expõe a aplicação à injeção. Um atacante pode fornecer um valor malicioso, como 0; DROP TABLE Patients, com resultados desastrosos.
A Solução: Consultas Parametrizadas
Consultas parametrizadas são a melhor defesa contra a injeção de SQL. Em vez de concatenar entradas na consulta, os valores do usuário são vinculados como parâmetros. Aqui está uma abordagem segura usando SQL Dinâmico:
Set query = "SELECT Name, Age FROM Patients WHERE Age > ?"
Set statement = ##class(%SQL.Statement).%New()
Set status = statement.%Prepare(query)
If status {
Set result = statement.%Execute(age)
While result.%Next() {
Write "Name: ", result.Name, ", Age: ", result.Age, !
}
}Aqui, o placeholder ? garante que o valor da idade seja tratado estritamente como dado, e não como código executável, reduzindo significativamente o risco de injeção.
SQL Embutido: Segurança Integrada
O SQL Embutido integra SQL diretamente ao ObjectScript, protegendo inerentemente contra injeção de SQL. A sintaxe de variável hospedeira (:variável) vincula parâmetros de forma segura em tempo de compilação:
&sql(SELECT Name, Age INTO :name, :age FROM Patients WHERE Age > :minAge)
Com SQL Embutido, não há mecanismo para concatenar diretamente a entrada bruta do usuário na consulta, evitando assim a injeção.
Comparando SQL Embutido e SQL Dinâmico
| Recurso | Embedded SQL | Dynamic SQL |
|---|---|---|
| Segurança | Seguro contra injeção devido às variáveis hospedeiras | Seguro se parametrizado; arriscado se não |
| Flexibilidade | Limitado (apenas consultas estáticas) | Altamente flexível para cenários dinâmicos |
| Capacidade de pesquisa | Fácil de localizar nas definições de classes |
Mais difícil de analisar; consultas estão em strings |
| Performance | Compilado no momento da compilação da classe | Analisado e otimizado em tempo de execução |
Quando Usar SQL Dinâmico
O SQL Dinâmico é útil quando a estrutura da consulta precisa ser determinada em tempo de execução, por exemplo, ao adicionar filtros opcionais:
Set query = "SELECT Name, Age FROM Patients"
If includeGender {
Set query = query_" WHERE Gender = ?"
}
Set statement = ##class(%SQL.Statement).%New()
Set status = statement.%Prepare(query)
If status {
Set result = statement.%Execute("Male")
}Lembre-se sempre de usar parametrização (?) para essas consultas construídas dinamicamente, a fim de manter a segurança.
Conclusões
O SQL Dinâmico permite a construção flexível de consultas, mas exige uso responsável para evitar riscos de injeção de SQL. Consultas parametrizadas tratam esse risco de forma eficaz. Enquanto isso, o SQL Embutido vem com proteções integradas, tornando-se uma excelente escolha para consultas estáticas. Ao usar essas abordagens de forma adequada, os desenvolvedores podem construir aplicações robustas e seguras com InterSystems IRIS.