문제

배경

기존 데이터 공급자를 분석하기로 계약했는데 다음 코드에 결함이 있다는 것을 알고 있습니다.하지만 그것이 얼마나 나쁜지 지적하려면 SQL 주입에 취약하다는 것을 증명해야 합니다.

질문

어떤 "Key" 매개변수가 PrepareString 함수를 실행하고 DROP 성명?

코드 조각

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
도움이 되었습니까?

해결책

귀하의 직접적인 질문에 대한 답변:이 코드는 SQL 삽입을 방지합니까?아니요

증거는 다음과 같습니다. 이 문자열을 prepareString 메서드를 통해 푸시합니다.

Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-"
Dim output = PrepareString(input)

Console.WriteLine(input)
Console.WriteLine(output)

데이터베이스에서 레코드를 가져오는 대신 완전히 준비된 SQL 문자열을 반환하도록 게시한 GetRecord 메서드를 수정했습니다.

Console.WriteLine(GetRecord(output))

그리고 이것이 출력입니다

Input  = ; Drop Table TableName; --
Output = '; Drop Table TableName; --
Query  = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --'

코드 한 줄을 추가합니다.

My.Computer.Clipboard.SetText(input)

그리고 SQL 주입을 완료하기 위해 웹 사이트의 입력 필드에 붙여넣기 위해 클립보드에 바로 복사해야 하는 문자열이 있습니다.

'; Drop Table TableName; - -

[StackOverflow의 사후 출력에서 ​​제어 문자가 생략되었으므로 출력을 생성하려면 코드 예제를 따라야 합니다.]

prepareString 메서드가 실행된 후에는 정확히 동일한 출력이 표시됩니다. Chr(8) ASCII 코드는 문자열을 닫는 추가 "'"를 제거하는 백스페이스입니다. 마지막에 내가 원하는 것을 자유롭게 추가하세요.귀하의 prepareString은 공백을 제거하기 위해 백스페이스 문자와 함께 - -를 실제로 사용하고 있기 때문에 표시되지 않습니다.

그러면 작성 중인 결과 SQL 코드는 Drop Table 문을 방해 없이 실행하고 쿼리의 나머지 부분을 즉시 무시합니다.

이것에 대한 재미있는 점은 인쇄할 수 없는 문자를 사용하여 기본적으로 모든 문자 검사를 우회할 수 있다는 것입니다.따라서 매개변수화된 쿼리를 사용하는 것이 가장 안전합니다(요청한 내용은 아니지만 이를 방지하는 가장 좋은 방법입니다).

다른 팁

의심스러운 질문에 대답하기 위해서는 효과가 없을 것입니다.

.Replace("``", "''") '' '로 합법적 인 질문을 방지합니다.

.Replace("´", "''") '´'로 합법적 인 질문을 방지합니다.

.Replace("--", "") 합법적 인 쿼리를 '-'로 막을 수 있습니다.

.Replace("''", "'") '' ''로 합법적 인 쿼리를 잘못 수정합니다.

등등.

또한 전체 탈출 문자 세트는 RDBMS마다 다를 수 있습니다. 매개 변수화 쿼리 ftw.

당신이 그냥 '' '로 교체하면 해고가 불가능하다고 생각합니다. 나는 탈출 인용문을 바꿀 수 있다고 들었습니다. 그래도 당신이 안전하다고 생각합니다.

나는 그것이 안전하다고 생각합니다 (적어도 SQL Server에서) s = s.Replace("'", "''"). 물론 매개 변수화 된 쿼리를 사용해야하지만 이미 알고 있습니다.

이것 MSDN 기사 당신이 찾아야 할 대부분의 물건을 다룹니다 (SQL 주입과 관련하여 모든 것을 말하는 것이 두렵습니다).

그러나 나는 다른 모든 사람들의 매개 변수 매개 변수 매개 변수에 반향 할 것입니다.

예를 들어, 일부 gotchas [편집 : 업데이트] :

  • 문자열이 "1 또는 1 = 1"이지 않습니까? 사용자가 모든 것을 되 찾을 수 있습니다.

  • 또는 더 나쁜 "1; DROP TABLE SOMEABLENAME"

확인하려는 기사에 따르면 :

; - 쿼리 구분자.

' - 문자 데이터 문자열 구분 기.

- 주석 구분 기호.

/* ... / - 주석 구분 자. / 사이의 텍스트 */는 서버에서 평가하지 않습니다.

XP_- XP_CMDSHELL과 같은 카탈로그 확장 저장 절차의 이름을 시작할 때 사용됩니다.

당신은 자신의 버전의 SQL Escaping을 구현하기 위해 캐릭터를 검은 목록에 시도하고 있습니다. 검토를 제안합니다 이 URL -SQL 이스케이프가 반드시 최악의 선택 일 필요는 없지만 (즉, 기존 앱을 신속하게 수정) 취약점을 피하기 위해 올바르게 수행해야합니다.

그 URL은 다음과 링크합니다 다른 페이지 저자가 기능을 제한하지 않고 취약점을 피하는 데 도움이되는 제안을 제공하는 SQL Server에서 탈출하는 경우.

그것이 도움이된다면, 기사는 버팀대를 탈출하는 것을 제안합니다 (나는 사각형 괄호라고 부르지 만 []).

코드를 사용하려고한다면 어떤 사람이 키를 전달할 수 있습니다 (; 선택 *에서 선택하고 원하는 테이블 목록을 얻으십시오.

코드에서 T-SQL 문을 종료하고 다른 문을 시작할 수있는 세미콜론을 확인하지 마십시오.

매개 변수화 된 쿼리와 함께 갈 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top