Estou tentando colocar alguma injeção anti-sql no java e estou com muita dificuldade em trabalhar com a função de cadeia "replaceAll". Por fim, preciso de uma função que converta qualquer existente \
para \\
, qualquer "
para \"
, qualquer '
para \'
e qualquer \n
para, \\n
para que quando a string for avaliada pelas injeções de SQL do MySQL sejam bloqueadas.
Eu criei um código com o qual estava trabalhando e todas \\\\\\\\\\\
as funções estão fazendo meus olhos enlouquecerem. Se alguém tiver um exemplo disso, eu apreciaria muito.
CREATE VIEW myview AS SELECT * FROM mytable WHERE col = ?
já que a instrução principal é uma declaração DDL , mesmo que a parte que você está tentando parametrizar seja realmente DML .Respostas:
PreparedStatements são o caminho a seguir, porque tornam impossível a injeção de SQL. Aqui está um exemplo simples, considerando a entrada do usuário como parâmetros:
Não importa quais caracteres estejam no nome e no email, esses caracteres serão colocados diretamente no banco de dados. Eles não afetarão a instrução INSERT de forma alguma.
Existem diferentes métodos de conjunto para diferentes tipos de dados - o que você usa depende dos campos de seu banco de dados. Por exemplo, se você tiver uma coluna INTEGER no banco de dados, use um
setInt
método A documentação PreparedStatement lista todos os diferentes métodos disponíveis para definir e obter dados.fonte
A única maneira de impedir a injeção de SQL é com SQL parametrizado. Simplesmente não é possível criar um filtro mais inteligente do que as pessoas que usam o SQL para viver.
Portanto, use parâmetros para todas as entradas, atualizações e cláusulas where. O SQL dinâmico é simplesmente uma porta aberta para hackers, e isso inclui SQL dinâmico em procedimentos armazenados. Parametrizar, parametrizar, parametrizar.
fonte
Se você realmente não pode usar a Opção 1 de Defesa: Instruções Preparadas (Consultas Parametrizadas) ou a Opção 2 de Defesa: Procedimentos Armazenados , não crie sua própria ferramenta, use a API de Segurança Corporativa da OWASP . No ESAPI da OWASP hospedado no Google Code:
Para obter mais detalhes, consulte Prevenção de injeção SQL em Java e Folha de dicas de prevenção de injeção SQL .
Preste atenção especial à Opção 3 de Defesa: Escapando Todas as Entradas Fornecidas pelo Usuário que apresenta o projeto ESAPI da OWASP ).
fonte
(Isso é uma resposta ao comentário do OP na pergunta original; concordo plenamente que o PreparedStatement é a ferramenta para este trabalho, não as expressões regulares.)
Quando você diz
\n
, você quer dizer a sequência\
+n
ou um caractere de avanço de linha real? Se for\
+n
, a tarefa é bem simples:Para corresponder a uma barra invertida na entrada, coloque quatro delas na sequência de caracteres regex. Para colocar uma barra invertida na saída, coloque quatro delas na cadeia de substituição. Isso pressupõe que você esteja criando as regexes e substituições na forma de literais Java String. Se você criá-los de outra maneira (por exemplo, lendo-os de um arquivo), você não precisa fazer tudo isso duas vezes.
Se você tiver um caractere de avanço de linha na entrada e desejar substituí-lo por uma sequência de escape, poderá fazer uma segunda passagem sobre a entrada com este:
Ou talvez você queira duas barras invertidas (não estou muito claro sobre isso):
fonte
As PreparedStatements são o caminho a seguir na maioria dos casos, mas não em todos os casos. Às vezes, você se encontra em uma situação em que uma consulta, ou parte dela, precisa ser criada e armazenada como uma string para uso posterior. Consulte a Folha de dicas sobre prevenção de injeção de SQL no site da OWASP para obter mais detalhes e APIs em diferentes linguagens de programação.
fonte
As instruções preparadas são a melhor solução, mas se você realmente precisar fazer isso manualmente, também poderá usar a
StringEscapeUtils
classe da biblioteca Apache Commons-Lang. Tem umescapeSql(String)
método, que você pode usar:import org.apache.commons.lang.StringEscapeUtils; … String escapedSQL = StringEscapeUtils.escapeSql(unescapedSQL);
fonte
O uso de uma expressão regular para remover texto que possa causar uma injeção de SQL parece que a instrução SQL está sendo enviada ao banco de dados por
Statement
umPreparedStatement
.Uma das maneiras mais fáceis de evitar uma injeção de SQL em primeiro lugar é usar um
PreparedStatement
, que aceita dados para substituir uma instrução SQL usando espaços reservados, que não depende de concatenações de cadeias para criar uma instrução SQL para enviar ao banco de dados.Para obter mais informações, o uso de instruções preparadas nos tutoriais Java seria um bom ponto de partida.
fonte
Caso você esteja lidando com um sistema legado ou tenha muitos lugares para mudar para
PreparedStatement
s em muito pouco tempo - por exemplo, se houver um obstáculo ao uso da melhor prática sugerida por outras respostas, tente o AntiSQLFilterfonte
Você precisa do seguinte código abaixo. À primeira vista, isso pode parecer com qualquer código antigo que eu criei. No entanto, o que fiz foi verificar o código fonte de http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.31/com/mysql/jdbc/PreparedStatement. java . Depois disso, examinei cuidadosamente o código de setString (int parameterIndex, String x) para encontrar os caracteres dos quais ele escapa e personalizo isso para minha própria classe, para que possa ser usado para os fins que você precisa. Afinal, se essa é a lista de caracteres dos quais o Oracle escapa, saber que isso é realmente reconfortante em termos de segurança. Talvez a Oracle precise de um empurrão para adicionar um método semelhante a este para a próxima versão principal do Java.
fonte
mysql-connector-java-xxx
, ocase '\u00a5'
ecase '\u20a9'
declarações parecem ter sido removidoorg.ostermiller.utils.StringHelper.escapeSQL()
oucom.aoindustries.sql.SQLUtility.escapeSQL()
.Depois de pesquisar em um monte de soluções de teste para evitar que o sqlmap seja injetado no sql, no caso de um sistema legado que não pode aplicar declarações preparadas em todos os lugares.
tópico java-security-cross-site-scripting-xss-and-sql-injection foi a solução
Tentei a solução de @Richard, mas não funcionou no meu caso. eu usei um filtro
fonte
java-security-cross-site-scripting-xss-and-sql-injection topic
? Estou tentando encontrar uma solução para um aplicativo herdado.De: [Fonte]
}
fonte
Se você estiver usando PL / SQL, também poderá usar
DBMS_ASSERT
lo, além de higienizar sua entrada, para que possa usá-lo sem se preocupar com injeções de SQL.veja esta resposta por exemplo: https://stackoverflow.com/a/21406499/1726419
fonte