카테고리 없음

[SQL] 작은 따옴표를 이스케이프하고 사용자 입력을 작은 따옴표로 묶어 SQL 주입으로부터 보호 할 수 있습니까?

행복을전해요 2021. 2. 18. 19:21

우선, 그것은 단지 나쁜 습관입니다. 입력 유효성 검사는 항상 필요하지만 항상 불확실합니다.
더 나쁜 것은 블랙리스트 유효성 검사는 항상 문제가 있습니다. 허용하는 값 ​​/ 형식을 명시적이고 엄격하게 정의하는 것이 훨씬 낫습니다. 물론 이것이 항상 가능한 것은 아니지만 어느 정도는 항상 이루어져야합니다.
주제에 대한 일부 연구 논문 :

  • http://www.imperva.com/docs/WP_SQL_Injection_Protection_LK.pdf
  • http://www.it-docs.net/ddata/4954.pdf (공개, 마지막 것은 내 것이 었습니다;))
  • https://www.owasp.org/images/d/d4/OWASP_IL_2007_SQL_Smuggling.pdf (더 이상 사용할 수없는 이전 문서를 기반으로 함)

요점은 모든 블랙리스트 (및 너무 허용적인 화이트리스트)를 우회 할 수 있다는 것입니다. 내 논문의 마지막 링크는 인용문 이스케이프조차 우회 할 수있는 상황을 보여줍니다.

이러한 상황이 귀하에게 해당되지 않더라도 여전히 나쁜 생각입니다. 또한 앱이 사소한 것이 아니라면 유지 관리와 일정량의 거버넌스를 처리해야합니다. 항상 어디서나 올바르게 수행되도록하려면 어떻게해야합니까?

이를 수행하는 적절한 방법 :

  • 화이트리스트 유효성 검사 : 유형, 길이, 형식 또는 허용되는 값
  • 블랙리스트를 원하시면 바로 진행하십시오. 견적 이스케이프는 좋지만 다른 완화의 맥락에서 볼 수 있습니다.
  • Command 및 Parameter 개체를 사용하여 준비 및 유효성 검사
  • 매개 변수화 된 쿼리 만 호출합니다.
  • 더 나은 방법은 저장 프로 시저를 독점적으로 사용하는 것입니다.
  • 동적 SQL을 사용하지 말고 문자열 연결을 사용하여 쿼리를 작성하지 마십시오.
  • SP를 사용하는 경우 테이블에 직접 액세스하지 않고 필요한 SP 만 실행하도록 데이터베이스의 권한을 제한 할 수도 있습니다.
  • 전체 코드베이스가 SP를 통해서만 DB에 액세스하는지 쉽게 확인할 수도 있습니다.
-------------------

좋습니다.이 답변은 질문 업데이트와 관련이 있습니다.

"누군가가이 삭제 방법에 대한 SQL 주입 공격을 마운트하는 특정 방법을 알고 있다면 나는 그것을보고 싶습니다."

이제 MySQL 백 슬래시 이스케이프 외에도 실제로 MSSQL에 대해 이야기하고 있다는 점을 고려하면 실제로 SQL에서 코드를 삽입하는 3 가지 가능한 방법이 있습니다.

sSanitizedInput = " '"& Replace (sInput, "'", " ''") & " '"

이 모든 것이 항상 유효하지는 않으며 주변의 실제 코드에 크게 의존한다는 점을 고려하십시오.

  1. 2 차 SQL 주입- 이스케이프 처리 데이터베이스에서 검색된 데이터를 기반으로 SQL 쿼리가 다시 작성되는 경우 데이터는 이스케이프되지 않은 상태로 연결되며 간접적으로 SQL 주입 될 수 있습니다. 보다
  2. 문자열 자르기-(조금 더 복잡함)-시나리오는 사용자 이름과 비밀번호라는 두 개의 필드가 있고 SQL이 두 필드를 연결하는 것입니다. 그리고 두 필드 (또는 첫 번째 필드)에는 길이에 대한 엄격한 제한이 있습니다. 예를 들어 사용자 이름은 20 자로 제한됩니다. 이 코드가 있다고 가정합니다.
username = left(Replace(sInput, "'", "''"), 20)
  

그런 다음 얻는 것은 사용자 이름이며 이스케이프 처리 된 다음 20 자로 잘립니다. 여기서 문제는 20 번째 문자 (예 : 19a 이후)에 내 따옴표를 붙이고 이스케이프 따옴표 (21 번째 문자에서)를 잘라냅니다. 그런 다음 SQL

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

앞서 언급 한 잘못된 사용자 이름과 결합하면 암호가 이미 따옴표 밖에 있고 페이로드가 직접 포함됩니다.
3. 유니 코드 밀수가 - 특정 상황에서, 높은 수준의 유니 코드 문자를 전달하는 것이 가능하다는 것을 보이는 견적 같은, 그러나 아니다 - 그것은 갑자기 데이터베이스에 도달 할 때까지 이있다 . 검증 할 때 견적이 아니므로 쉽게 진행됩니다 ... 자세한 내용은 이전 응답을 참조하고 원본 연구에 링크하십시오.

-------------------

간단히 말해서, 쿼리를 스스로 이스케이프하지 마십시오. 당신은 뭔가 잘못 될 수밖에 없습니다. 대신 매개 변수화 된 쿼리를 사용하거나, 어떤 이유로 그렇게 할 수없는 경우이를 수행하는 기존 라이브러리를 사용하십시오. 스스로 할 이유가 없습니다.

-------------------

질문을 받고 오랜만이라는 걸 알지만 ..

'인수 인용'절차에 대한 공격을 시작하는 한 가지 방법은 문자열 자르기를 사용하는 것입니다. MSDN에 따르면 SQL Server 2000 SP4 (및 SQL Server 2005 SP1)에서 너무 긴 문자열은 조용히 잘립니다.

문자열을 인용하면 문자열의 크기가 증가합니다. 모든 아포스트로피가 반복됩니다. 그런 다음 SQL의 일부를 버퍼 외부로 밀어 넣는 데 사용할 수 있습니다. 따라서 where 절의 일부를 효과적으로 제거 할 수 있습니다.

이것은 아마도 모든 검사를 수행하지 않기 위해 'update'문을 남용 할 수있는 'user admin'페이지 시나리오에서 가장 유용 할 것입니다.

따라서 모든 인수를 인용하기로 결정한 경우 문자열 크기에 어떤 일이 발생하는지 알고 잘림이 발생하지 않는지 확인하십시오.

매개 변수를 사용하는 것이 좋습니다. 항상. 데이터베이스에 적용 할 수 있으면 좋겠어요. 그리고 부작용으로 더 많은 명령문이 동일하게 보이기 때문에 더 나은 캐시 히트를 얻을 가능성이 더 큽니다. (이것은 Oracle 8에서 확실히 사실입니다)

-------------------

필자는 처음부터 쿼리를 작성하는 것이 유일한 해답 인 '고급 검색'기능을 처리 할 때이 기술을 사용했습니다. (예 : 사용자가 제품 속성에 대한 제한 조건의 무제한 세트를 기반으로 제품을 검색하고 열과 허용 된 값을 GUI 제어로 표시하여 사용자의 학습 임계 값을 줄일 수 있도록합니다.)

그 자체로 안전한 AFAIK입니다. 그러나 다른 응답자가 지적했듯이 백 스페이스 이스케이프를 처리해야 할 수도 있습니다 (적어도 ADO 또는 ADO.NET을 사용하여 쿼리를 SQL Server에 전달할 때는 아니지만 모든 데이터베이스 또는 기술을 보증 할 수는 없습니다).

문제는 어떤 문자열에 사용자 입력 (항상 잠재적으로 악성)이 포함되어 있는지, 어떤 문자열이 유효한 SQL 쿼리인지 확인해야한다는 것입니다. 함정 중 하나는 데이터베이스의 값을 사용하는 경우입니다.이 값은 원래 사용자가 제공 한 것입니까? 그렇다면 이스케이프해야합니다. 내 대답은 SQL 쿼리를 구성 할 때 가능한 한 늦게 (하지만 나중에는 안됩니다!) 위생 처리를 시도하는 것입니다.

그러나 대부분의 경우 매개 변수 바인딩이 더 간단합니다.

-------------------

입력 위생은 당신이 반쯤하려는 것이 아닙니다. 엉덩이 전체를 사용하십시오. 텍스트 필드에 정규식을 사용하십시오. 숫자를 적절한 숫자 유형으로 캐스트하고 작동하지 않는 경우 유효성 검사 오류를보고합니다. 입력에서 '-와 같은 공격 패턴을 검색하는 것은 매우 쉽습니다. 사용자의 모든 입력이 적대적이라고 가정합니다.

-------------------

당신이 아는 것처럼 어쨌든 그것은 나쁜 생각입니다.

다음과 같이 문자열에서 따옴표를 이스케이프하는 것과 같은 것은 어떻습니까?

교체 결과 : \ ''

백 슬래시가 첫 번째 따옴표를 이스케이프하면 두 번째 따옴표가 문자열을 끝낸 것입니다.

-------------------

간단한 대답 : 가끔 작동하지만 항상 작동하지는 않습니다. 수행 하는 모든 작업 에 화이트리스트 유효성 검사를 사용 하고 싶지만 이것이 항상 가능한 것은 아니라는 것을 알고 있으므로 최선의 추측 블랙리스트를 사용해야합니다. 마찬가지로 모든 항목 에서 매개 변수화 된 저장된 procs를 사용하고 싶지만 다시 한 번 이것이 항상 가능한 것은 아니므로 매개 변수와 함께 sp_execute를 사용해야합니다.

사용할 수있는 블랙리스트를 처리 할 수있는 방법이 있습니다 (그리고 일부 화이트리스트도).

괜찮은 글이 여기에 있습니다 : http://www.owasp.org/index.php/Top_10_2007-A2

이 작업을 신속하게 수행하여 실제 위치를 확보 할 시간을 제공해야하는 경우 수행하십시오. 하지만 당신이 안전하다고 생각하지 마세요.

-------------------

SQL 주입으로부터 안전하기 위해 예외없이 두 가지 방법이 있습니다. 준비된 문 또는 실용화 된 저장 프로 시저

-------------------

매개 변수화 된 쿼리를 사용할 수있는 경우 항상이를 사용해야합니다. 필요한 것은 하나의 쿼리가 네트워크를 통해 빠져 나가고 DB가 위험에 처하는 것입니다.

-------------------

예, 누군가 SET QUOTED_IDENTIFIER OFF를 실행 하고 큰 따옴표를 사용할 때까지 바로 작동 합니다.

편집 : 악의적 인 사용자가 인용 식별자를 끄는 것을 허용하지 않는 것만 큼 간단하지 않습니다.

SQL Server 용 SQL Server Native Client ODBC 드라이버 및 SQL Server 용 SQL Server Native Client OLE DB 공급자는 연결시 QUOTED_IDENTIFIER를 자동으로 ON으로 설정합니다. ODBC 데이터 원본, ODBC 연결 특성 또는 OLE DB 연결 속성에서 구성 할 수 있습니다. SET QUOTED_IDENTIFIER의 기본값은 DB-Library 애플리케이션에서 연결하는 경우 OFF입니다.

저장 프로 시저가 만들어지면 SET QUOTED_IDENTIFIER 및 SET ANSI_NULLS 설정이 캡처되어 해당 저장 프로 시저의 후속 호출에 사용됩니다 .

SET QUOTED_IDENTIFIER는 ALTER DATABASE의 QUOTED_IDENTIFER 설정 에도 해당합니다.

SET QUOTED_IDENTIFIER는 구문 분석 시간에 설정됩니다 . 구문 분석시 설정은 SET 문이 일괄 처리 또는 저장 프로 시저에있는 경우 코드 실행이 실제로 해당 지점에 도달했는지 여부에 관계없이 적용됨을 의미합니다. SET 문은 문이 실행되기 전에 적용됩니다.

QUOTED_IDENTIFIER는 사용자가 알지 못하는 사이에 여러 가지 방법으로 작동하지 않을 수 있습니다. 인정합니다-이것은 당신이 찾고있는 총기 익스플로잇은 아니지만 꽤 큰 공격 표면입니다. 물론, 큰 따옴표도 이스케이프 처리했다면-우리가 시작했던 곳으로 돌아 왔습니다. ;)

-------------------

다음과 같은 경우 방어가 실패합니다.

  • 쿼리에 문자열이 아닌 숫자가 필요합니다.
  • 다음을 포함하여 작은 따옴표를 나타내는 다른 방법이 있습니다.
    • \ 039와 같은 이스케이프 시퀀스
    • 유니 코드 문자

(후자의 경우 교체를 완료 한 후에 만 ​​확장되어야합니다.)

-------------------

Patrick, 모든 입력, 심지어 숫자 입력에 작은 따옴표를 추가하고 있습니까? 숫자 입력이 있지만 주위에 작은 따옴표를 넣지 않으면 노출이 발생합니다.

-------------------

사용자 입력을 완전히 삭제하는 것은 얼마나 추악한 코드일까요! 그런 다음 SQL 문에 대한 투박한 StringBuilder입니다. 준비된 명령문 방법은 훨씬 더 깨끗한 코드를 생성하며 SQL 주입의 이점은 정말 멋진 추가 기능입니다.

또한 왜 바퀴를 재발 명합니까?

-------------------

작은 따옴표를 두 개의 작은 따옴표로 변경하는 대신 아포스트로피, 따옴표로 변경하거나 완전히 제거하지 않는 이유는 무엇입니까?

어느 쪽이든, 그것은 약간의 문제입니다 ... 특히 합법적으로 작은 따옴표를 사용할 수있는 것 (이름과 같은)이있을 때 ...

참고 :이 방법은 또한 앱에서 작업하는 모든 사람이 입력이 데이터베이스에 도달하기 전에 항상 입력을 삭제하는 것을 기억한다고 가정합니다. 이는 대부분의 경우 현실적이지 않을 것입니다.

-------------------

문자열에 대해 작동하는 솔루션을 찾을 수 있지만 숫자 조건 자의 경우 숫자로만 전달되는지 확인해야합니다 (간단한 검사는 int / double / decimal로 구문 분석 할 수 있다는 것입니다).

많은 추가 작업입니다.

-------------------

작동 할 수도 있지만 나에게는 약간 멍청한 것 같습니다. 대신 정규식에 대해 테스트하여 각 문자열이 유효한지 확인하는 것이 좋습니다.

-------------------

예, 가능하다면 ...

주제를 연구 한 후, 제안한대로 삭제 된 입력이 안전하다고 생각하지만 다음 규칙에 따라야합니다.

  1. 사용자로부터 오는 문자열 값이 문자열 리터럴 이외의 다른 값이되도록 허용하지 않습니다 (예 : "여기에 추가 SQL 열 이름 / 표현식 입력 :"구성 옵션을 제공하지 마십시오). 문자열 이외의 값 유형 (숫자, 날짜, ...) : 기본 데이터 유형으로 변환하고 각 데이터 유형의 SQL 리터럴에 대한 루틴을 제공합니다.

    • SQL 문은 유효성 검사에 문제가 있습니다.
  2. 당신이 중 하나를 사용 nvarchar/ nchar열 (와 접두어 문자열 리터럴 N로가는) 또는 한계 값 varchar/ charASCII 문자를 열 전용 (예 : 던져 예외 SQL 문을 만들 때)

    • 이렇게하면 CHAR (700)에서 CHAR (39) 로의 자동 아포스트로피 변환을 피할 수 있습니다 (및 기타 유사한 유니 코드 해킹).
  3. 항상 실제 열 길이에 맞게 값 길이의 유효성을 검사합니다 (더 길면 예외 발생).

    • 잘림시 발생한 SQL 오류를 우회 할 수있는 SQL Server에 알려진 결함이 있습니다 (자동 잘림으로 이어짐).
  4. 당신 SET QUOTED_IDENTIFIER은 항상ON

    • 주의하십시오. 이것은 구문 분석 시간에 적용됩니다. 즉, 액세스 할 수없는 코드 섹션에서도 적용됩니다.

이 4 가지 사항을 준수하면 안전해야합니다. 이들 중 하나라도 위반하면 SQL 주입 방법이 열립니다.



출처
https://stackoverflow.com/questions/22079869