No artigo anterior, já falamos sobre a essência das vulnerabilidades de ataque de injeção de SQL causadas por codificação inadequada por parte dos programadores. Agora continuaremos falando sobre como codificar corretamente para não sermos atacados pela injeção de SQL. problema Vamos primeiro dar uma olhada em um trecho de código:
Copie o código do código da seguinte forma:
dim sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = '|e|exec|inserir|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare
SQL_inj = divisão(SQL_Injdata,|)
Se Request.QueryString<> Então
Para cada SQL_Get em Request.QueryString
Para SQL_Data = 0 para Ubound (SQL_inj)
se instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Então
Response.Write <Script Language=javascript>alert('Solicitações do sistema anti-injeção SQL, por favor, não tente injetar novamente!');
Resposta.fim
terminar se
próximo
Próximo
Terminar se
Se Request.Form<> Então
Para cada Sql_Post em Request.Form
Para SQL_Data = 0 para Ubound (SQL_inj)
se instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Então
Response.Write <Script Language=javascript>alert('Solicitações do sistema anti-injeção SQL, por favor, não tente injetar novamente!');
Resposta.fim
terminar se
próximo
próximo
terminar se
Este é um código anti-injeção ASP amplamente popular na Internet. A ideia é verificar os dados enviados pelo método Post e pelo método Get e evitar a injeção de SQL filtrando caracteres confidenciais como Insert, Update e And. , etc. Em teoria, se filtrarmos caracteres suficientes, podemos garantir definitivamente que não seremos atacados por injeção de SQL, mas tenha cuidado. Leia este código e preste atenção em como ele é julgado através da função instr. Ou seja, se eu quiser filtrar o caractere e, não é apenas a palavra E que é filtrada, mas também todas as palavras. contendo e. Todas as palavras com as seguintes combinações de caracteres foram filtradas, como ilha, continente, mão... Se esses caracteres fossem filtrados, alguém ainda estaria disposto a usá-los? Portanto, esse método de filtragem de caracteres sensíveis não tem sentido algum. O que me surpreende é que esse lixo seja realmente postado na Internet como um clássico.
Algumas pessoas dizem que os ataques de injeção de SQL são causados pela emenda de strings de consulta SQL, portanto, usar procedimentos armazenados sem emendar strings de consulta SQL pode protegê-lo de ataques de injeção de SQL. Não necessariamente, vejamos um exemplo de ataque de injeção de procedimento armazenado.
O código do procedimento armazenado dt_GetNews é o seguinte:
CRIAR PROCEDIMENTO dt_GetNews
@newstypeint
COMO
selecione * nas notícias onde newstype=@newstype
IR
Código de chamada:
<%
dim adoconexão
definir adoconnection=server.createobject(adodb.connection)
'.........O código relevante para estabelecer uma conexão de banco de dados é omitido aqui
adoconnection.execute exec dt_GetNews +request(tipo de notícia)
adoconnection.fechar
%>
Se o valor de request(newstype) for igual a 1, o resultado da operação é retornar todos os registros com o campo newstype na tabela news sendo 1. Porém, se o valor de request(newstype) for 1; , o resultado retornado é que a tabela de notícias foi excluída.
Pode-se ver neste exemplo que mesmo usando procedimentos armazenados ainda será atacado. Além disso, select * from news onde newstype=@newstype não está emendando, então não há conexão inevitável entre a emenda de strings de consulta SQL e ataques de injeção SQL. procedimentos armazenados podem não ser capazes de proteger contra ataques de injeção.
Então, como você escreve sem ser atacado pela injeção de SQL? Abaixo, apresentarei um método definitivo, que é muito simples e primitivo, que é a verificação do tipo de dados e a substituição de aspas simples. Seja Oracle, Sql Server, mySql, Access ou outros bancos de dados relacionais, os tipos de campo podem ser divididos aproximadamente em duas categorias: tipos numéricos (como int, float, etc.) e tipos de caracteres (como char, varchar, etc.). ). As instruções SQL correspondentes são ligeiramente diferentes dependendo do tipo de campo, como:
O campo newstype em Select * from news onde newstype=1 deve ser um campo numérico.
select * from news where newstype='social news' o campo newstype deve ser um campo de caractere.
Para campos numéricos, o que devemos fazer é verificar o tipo de dados do parâmetro. Por exemplo, quando construímos uma instrução de consulta usando select * from news onde newstype=+v_newstype, devemos verificar o tipo de dados da variável v_newstype. é pelo menos Deve ser um número, que pode ser um número inteiro ou de ponto flutuante. Se tal verificação for feita, select * from news where newstype=+v_newstype nunca construirá algo semelhante a select * from news where newstype=1. ;derrubar Declarações como notícias de mesa. A razão pela qual o ASP é mais vulnerável a ataques do que ASP.Net, JSP, etc. é porque as variáveis no ASP não precisam ser declaradas e o tipo da variável não é claro.
Para campos de caracteres, o que devemos fazer é processar aspas simples ('). O método de processamento é substituir uma aspa simples por duas aspas simples (''). Quando newstype='+v_newstype+' é usado para construir a instrução de consulta, as aspas simples em v_newstype devem ser substituídas por duas aspas simples, porque em SQL a parte entre duas aspas simples representa uma string e duas consecutivas. quote representa um caractere de aspas simples. Após esse processamento, veremos o método de construção de select * from news onde newstype='+v_newstype+' Quando o valor de v_newstype é:
Notícias sociais'; notícias da tabela suspensa -
Depois de substituir uma aspa simples por duas aspas simples, o valor de v_newstype se torna:
Notícias sociais''; notícias da tabela suspensa -
A instrução SQL construída se torna:
selecione * de notícias onde newstype='notícias sociais'';descarte notícias da tabela—'
O resultado da consulta é retornar registros cujo valor do campo newstype na tabela de notícias é social news';drop table news--, sem fazer com que a tabela de notícias seja excluída como antes.
Além disso, não é apenas a instrução Select que precisa ser processada, incluindo Insert, Update, Delete, Exec, etc., você pode dar uma olhada nos seguintes métodos de injeção:
Na estrutura insira em news(title) valores('+v_title+'),
Quando v_title=123';descartar tabela news--';
Ao atualizar o conjunto de notícias /> quando v_title=123'-- ou v_id=1;drop table news--, então não é apenas um problema com a instrução Select, mas outras instruções podem ter problemas, não se concentre apenas em Select
Resumindo, depois de verificar o tipo de dados e processar as aspas simples, mesmo que tenha todas as habilidades, não conseguirá voar para fora da palma do meu Tathagata.