Será que este código de injeção SQL prevent?
-
05-07-2019 - |
Pergunta
Fundo
Eu fui contratado para analisar um provedor de dados existente e eu sei o seguinte código está com defeito; mas, a fim de salientar como é ruim, eu preciso provar que é suscetível a injeção de SQL.
Pergunta ??h3>
O parâmetro "Key" pode quebrar a função PrepareString
e permitir-me para executar uma instrução DROP
?
Fragmento de Código
Public Shared Function GetRecord(ByVal Key As String) As Record
Dim Sql As New StringBuilder()
With Sql
.Append("SELECT * FROM TableName")
If String.IsNullOrEmpty(Agency) Then
.Append(" ORDER BY DateAdded")
Else
.Append(" WHERE Key = '")
.Append(PrepareString(Key))
.Append("'")
End If
End With
Return ExecuteQuery(Sql.ToString())
End Function
Public Shared Function PrepareString(ByVal Value As String) As String
Return Value.Replace("''", "'") _
.Replace("'", "''") _
.Replace("`", "''") _
.Replace("´", "''") _
.Replace("--", "")
End Function
Solução
Em resposta à sua pergunta direta: Será que este código de injeção SQL Prevent: Não
Aqui está a prova - empurrar essa corda através do método PrepareString:
Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-"
Dim output = PrepareString(input)
Console.WriteLine(input)
Console.WriteLine(output)
Eu modifiquei o método GetRecord você postou para retornar a string SQL totalmente preparado, em vez de obter o registro do banco de dados:
Console.WriteLine(GetRecord(output))
E esta é a saída
Input = ; Drop Table TableName; --
Output = '; Drop Table TableName; --
Query = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --'
Adicione 1 linha extra de código:
My.Computer.Clipboard.SetText(input)
E você tem a seqüência que você precisa copiado direito à sua área de transferência para colar em seu campo de entrada no site para completar a sua injeção de SQL:
'; Drop Table TableName; - -
[Observando que os caracteres de controle foram omitidos a saída mensagem por StackOverflow, então você tem que seguir o exemplo de código para criar a sua saída]
Depois que o método PrepareString é executado, ele terá exatamente a mesma saída - a Chr (8) código ASCII é o retrocesso que irá remover o extra """ que você está anexando a mina que irá fechar sua seqüência e, em seguida, Eu sou livre para adicionar o que eu quero no final. Será que o seu PrepareString não ver o meu - porque eu estou realmente usando - -. com um caráter de retrocesso para remover o espaço
O código SQL resultante que você está construindo, em seguida, executar a minha declaração Drop Table livre e prontamente ignorar o resto de sua consulta.
A coisa divertida sobre isso é que você pode usar caracteres não-imprimíveis, basicamente, de bypass qualquer verificação de personagem que você pode inventar. Portanto, é mais seguro usar consultas parametrizadas (que não é o que você pediu, mas é o melhor caminho para evitar isso).
Outras dicas
Para responder à sua pergunta questionável, não, não iria funcionar.
.Replace("``", "''")
impediria consultas legítimas com '''
.Replace("´", "''")
impediria consultas legítimas com '''
.Replace("--", "")
impediria consultas legítimas com '-' neles
.Replace("''", "'")
iria modificar incorretamente consultas legítimas com '' '' neles
e assim por diante.
Além disso, o conjunto completo de caracteres de escape pode variar de um RDBMS para outro. consultas parametrizadas FTW.
Eu acho que é unhackable se você apenas substituir 'com ''. Ouvi dizer que é possível mudar o caracter de aspas fuga, o que poderia quebrar isso, porém eu não tenho certeza. Eu acho que você são embora seguro.
Eu acho que é seguro (pelo menos no servidor SQL), e eu também acho que a única coisa que você realmente precisa fazer é s = s.Replace("'", "''")
. Claro que você deve usar consultas parametrizadas, mas você já sabe disso.
tampas Este artigo MSDN a maioria das coisas que você precisa olhar para fora (eu tenho medo de dizer tudo quando se trata de injeção de SQL).
Mas vou ecoar o sentimento de todo mundo de parâmetros Parâmetros Parâmetros.
Quanto ao seu exemplo, algumas pegadinhas [Edit: Atualizado estes]:
-
não seria a string "1 OR 1 = 1" permitem que o usuário voltar tudo -
ou pior "1; mesa AlgumNomeDeTabela queda"
De acordo com o artigo que deseja verificar para:
; -. Consulta delimitador
' -. Character string de dados delimitador
- -. Delimitador de comentário
/ * ... / - delimitadores de comentário. Texto entre / e não é avaliado * / por o servidor.
xp_ - Usado no início do nome do catalogar-expandido procedimentos armazenados, tais como xp_cmdshell.
Você está tentando caracteres de lista negra para implementar sua própria versão do SQL escapar. Gostaria de sugerir rever esta URL - SQL escapar não é necessariamente a pior escolha (ou seja rapidamente fixação de apps existentes), mas ele precisa ser feito direito de vulnerabilidades a evitar.
que os links URL para outra página para escapar no SQL Server onde o autor dá sugestões que ajudam a evitar vulnerabilidades sem limitar a funcionalidade.
Se ajudar, os artigos sugerem escapar chaves também (eu os chamo colchetes - mas [])
.Se você tentar usar o código de alguém poderia passar uma chave (; select * da tabela;. E obter uma lista do que nunca mesa que eles querem
Em seu código a sua não verificação para o ponto e vírgula que permite encerrar uma instrução T-SQL e começar outra.
Eu iria com uma consulta parametrizada.