[sql] 작은 따옴표와 주변 따옴표를 작은 따옴표로 이스케이프 처리하여 SQL 삽입으로부터 보호 할 수 있습니까?

매개 변수가있는 SQL 쿼리가 사용자 입력이 포함 된 쿼리를 작성할 때 사용자 입력을 소독하는 가장 좋은 방법이라는 것을 알고 있지만 사용자 입력을 가져 와서 작은 따옴표를 이스케이프 처리하고 전체 문자열을 작은 따옴표로 묶는 것이 어떤 문제인지 궁금합니다. 코드는 다음과 같습니다.

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

사용자가 입력하는 작은 따옴표는 큰 따옴표로 대체되어 사용자가 문자열을 종료하는 기능을 제거하므로 세미콜론, 퍼센트 기호 등과 같이 입력 할 수있는 모든 것이 문자열의 일부가되고 실제로 명령의 일부로 실행되지 않았습니다.

우리는 작은 따옴표가 유일한 문자열 구분 기호이고 문자열 구분 기호를 이스케이프 처리하는 유일한 방법이라고 생각하는 Microsoft SQL Server 2000을 사용하고 있으므로 사용자가 입력 한 내용을 실행할 수있는 방법이 없습니다.

나는 이것에 대해 SQL 주입 공격을 시작하는 방법을 보지 못하지만, 이것이 나에게 보이는 것처럼 방탄이라면 다른 사람이 이미 그것을 생각했을 것이고 일반적인 관행이라는 것을 알고 있습니다.

이 코드에 어떤 문제가 있습니까? 이 살균 기술을지나 SQL 주입 공격을받을 수있는 방법이 있습니까? 이 기술을 이용하는 샘플 사용자 입력은 매우 유용합니다.


최신 정보:

나는 여전히이 코드에 대한 SQL 인젝션 공격을 효과적으로 시작하는 방법을 모른다. 소수의 사람들은 백 슬래시가 작은 따옴표를 이스케이프하고 다른 하나는 문자열을 끝내도록 남겨두고 나머지 문자열은 SQL 명령의 일부로 실행되도록 제안했습니다.이 방법은 SQL을 MySQL 데이터베이스이지만 SQL Server 2000에서는 작은 따옴표를 피할 수있는 유일한 방법은 다른 작은 따옴표를 사용하는 것입니다. 백 슬래시는 그것을하지 않습니다.

작은 따옴표 이스케이프를 중지하는 방법이 없으면 나머지 사용자 입력은 모두 하나의 연속 문자열로 간주되므로 실행되지 않습니다.

입력을 삭제하는 더 좋은 방법이 있다는 것을 알고 있지만 위에 제공된 방법이 효과가없는 이유를 배우는 데 더 관심이 있습니다. 이 소독 방법에 대해 SQL 주입 공격을 수행하는 특정 방법을 아는 사람이 있다면 그것을보고 싶습니다.



답변

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

요점은, 당신이하는 모든 블랙리스트 (그리고 너무 허용되는 화이트리스트)는 무시할 수 있다는 것입니다. 내 논문에 대한 마지막 링크는 따옴표 이스케이프를 우회 할 수있는 상황을 보여줍니다.

이러한 상황이 자신에게 적용되지 않더라도 여전히 나쁜 생각입니다. 또한 앱이 사소한 것이 아니라면 유지 관리 및 일정 정도의 거버넌스를 처리해야합니다.

올바른 방법 :

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

답변

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

“누군가이 살균 방법에 대해 SQL 주입 공격을 수행하는 특정 방법을 알고 있다면 그것을보고 싶을 것입니다.”

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

sSanitizedInput = ” ‘”& 바꾸기 (sInput, “‘”, ” ””) & ” ‘”

이것들이 항상 유효한 것은 아니며 주변의 실제 코드에 크게 의존한다는 것을 고려하십시오.

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

그런 다음 얻는 것은 사용자 이름이며 이스케이프 된 다음 20 자로 잘립니다. 여기서 문제-나는 20 번째 문자 (예 : 19 a 이후)에 내 인용문을 붙이고 탈출 인용문은 (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 쿼리를 구성 할 때 가능한 한 늦게 위생 처리하는 것입니다 (그러나 나중에는 아닙니다!).

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


답변

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


답변

당신이 알고있는 것처럼 어쨌든 나쁜 생각입니다.

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

교체하면 \ ”

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