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

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
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top