매개 변수화 된 쿼리에 대한 의존성이 SQL 삽입을 막는 유일한 방법입니까?


13

SQL 인젝션 공격에서 본 모든 것은 매개 변수가있는 쿼리, 특히 저장 프로 시저의 쿼리가 이러한 공격을 막을 수있는 유일한 방법임을 암시하는 것 같습니다. 내가 암흑 시대로 돌아 왔을 때 저장 프로시 저는 관리가 덜한 것으로 보였기 때문에 좋지 않은 관행으로 여겨졌다. 덜 테스트 가능; 고도로 결합 된; 하나의 벤더에 시스템을 잠그고; ( 이 질문 은 다른 이유를 다룹니다).

내가 일할 때 프로젝트는 실제로 그러한 공격의 가능성을 알지 못했습니다. 다양한 종류의 손상으로부터 데이터베이스를 보호하기 위해 다양한 규칙이 채택되었습니다. 이러한 규칙은 다음과 같이 요약 될 수 있습니다.

  1. 클라이언트 / 응용 프로그램이 데이터베이스 테이블에 직접 액세스 할 수 없었습니다.
  2. 모든 테이블에 대한 모든 액세스는 뷰를 통해 이루어졌으며 기본 테이블에 대한 모든 업데이트는 트리거를 통해 수행되었습니다.
  3. 모든 데이터 항목에 도메인이 지정되었습니다.
  4. 데이터 항목을 무효화 할 수 없었습니다. 이것은 DBA가 때때로 치아를 연마하는 데 영향을 미쳤습니다. 그러나 집행되었다.
  5. 역할과 권한은 적절하게 설정되었습니다. 예를 들어 데이터를 변경할 수있는 권한을보기에만 제공하는 제한된 역할입니다.

이것과 같은 (강화 된) 규칙 세트는 (이 특정 세트는 아니지만) SQL 주입 공격을 방지하는 매개 변수화 된 쿼리에 대한 적절한 대안입니까? 그렇지 않다면 왜 안됩니까? 데이터베이스 (전용) 특정 조치를 통해 이러한 공격으로부터 데이터베이스를 보호 할 수 있습니까?

편집하다

최초의 응답에 비추어 질문의 강조는 약간 바뀌었다. 기본 질문은 변경되지 않았습니다.

편집 2

매개 변수화 된 쿼리에 의존하는 접근 방식은 시스템에 대한 공격을 방어하기위한 말초 단계에 지나지 않습니다. 더 기본적인 방어가 바람직하고 주입 공격에 대해 구체적으로 방어하기 위해 필요하지 않거나 덜 중요하지 않은 쿼리에 의존 할 수 있습니다.

내 질문에 암시적인 접근 방식은 데이터베이스 "갑옷"에 기반을 두 었으며 실행 가능한 옵션인지 알 수 없었습니다. 추가 연구에 따르면 그러한 접근 방식이 있음이 제안되었습니다. 이 유형의 접근 방식에 대한 몇 가지 포인터를 제공하는 다음 소스를 찾았습니다.

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

이 소스에서 얻은 주요 기능은 다음과 같습니다.

  1. 광범위한 보안 데이터 사전과 결합 된 광범위한 데이터 사전
  2. 데이터 사전에서 트리거, 쿼리 및 제약 조건 생성
  3. 코드 최소화 및 데이터 최대화

지금까지 내가 얻은 답변은 매우 유용하고 매개 변수가있는 쿼리를 무시하여 발생하는 어려움을 지적하지만 궁극적으로 그들은 원래 질문에 대답하지 않습니다 (현재 굵게 강조 표시).


나는 저장 프로 시저에 대한 논쟁을 사지 않습니다. 그들은 단순히 사실이 아닙니다.
Konrad Rudolph

널이없는 요구 사항은 무엇입니까?
Mark Canlas

2
@Konrad Rudolph-MySQL로 애플리케이션을 작성하고 DB2로 마이그레이션하기로 결정한 경우 저장 프로 시저가 호환 될 것이라고 생각하십니까? SQLLite로 마이그레이션하려는 경우에도 마찬가지입니까? 또한 스토어드 프로 시저가 C (DB2에있는)로 컴파일 된 경우 OS를 업그레이드한다고 가정하면 모두 재 컴파일해야합니다. 이것들은 합리적인 주장이지만 절대적이지는 않지만 합리적입니다.
Matthew Flynn

@ 매튜 듀. 나는 실제로 그것을 읽고 그것에 대해 언급 할 때 "매개 변수화 된 쿼리"를 생각하고있었습니다. 저장 프로 시저 = 전체 '다른 이야기.
Konrad Rudolph

답변:


25

저장된 procs는 주입을 자동으로 보호하지 않습니다. 이건 어때?

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

매개 변수가있는 쿼리를 사용하면 프로세스가 진행 중인지 여부에 관계없이 주입으로부터 보호됩니다.


procs가 아닌 매개 변수화 된 쿼리에 초점을 맞춰 주셔서 감사합니다. 그러나 데이터베이스와 같은 쿼리 이외의 방법, 특히 데이터베이스 레이어에만 국한된 방법으로 데이터베이스를 보호 할 수 있는지 묻고 있습니다.
Chris Walton

1
+1 그 외에도, 저장된 proc는 사용자가 데이터를 검색하는 방법을 유지하면서 테이블에 직접 액세스하지 못하게하는 유일한 방법이기 때문에 대부분 안전한 것으로 간주하고 싶습니다. 사용자가 중간에 아무 것도없이 클라이언트와 직접 데이터베이스에 액세스해야 할 때 행 기반 및 열 기반 권한을 보장하는 유일한 방법입니다.
팔콘

2
@Chris-Craig가 여기서 말하는 것은 프로세스가 실제로 사용자를 보호한다고 가정 할 수 없다는 것입니다. 아마도 완전한 대답이 아니며 제목의 가정을 더 잘 수정할 수 있습니다.
Jon Hopkins

@ 존-나는 질문의 제목을 변경하고 Craig의 수정에 비추어 질문을 약간 수정했습니다. 답장을 받기 전까지는 질문에 대한 가정을 알지 못했습니다.
Chris Walton

2
크레이그는 위의 기록 무엇을 강화하기 위해, 참조 databasesecurity.com/dbsec/lateral-sql-injection.pdf : "오라클의 취약점으로 새로운 종류의 측면 SQL 주입"
브루스 Ediger

11

그렇다면 SQL 주입 공격을 방지하는 저장 프로 시저의 적절한 대안과 같은 일련의 규칙이 적용됩니까? 그렇지 않다면 왜 안됩니까?

아니요. 개발자에게 큰 페널티를주기 때문입니다. 항목 별 분석 :

1. 클라이언트 / 응용 프로그램이 데이터베이스 테이블에 직접 액세스 할 수 없었습니다.

역할을 사용하십시오. 클라이언트는 액세스가 필요한 테이블 (및 가능한 경우 행)에 대한 SELECT, INSERT, UPDATE 및 DELETE 액세스 권한 만있는 제한된 역할을 통해서만 DB에 액세스 할 수 있어야합니다. 클라이언트가 스팸을 보내거나 모든 항목을 삭제할 수 없도록하려면 데이터 수정에 API를 사용하십시오.

2. 모든 테이블에 대한 모든 액세스는 뷰를 통해 이루어졌습니다.

이는 뷰의 효율성에 따라 무시할 수있는 수준에서 막대한 성능 비용에 이르기까지 다양합니다. 불필요한 복잡성으로 인해 개발 속도가 느려집니다. 역할을 사용하십시오.

3. 모든 데이터 항목에 도메인이 지정되었습니다.

유지 관리해야 할 작업이 많을 수 있으며 별도의 테이블로 정규화해야합니다.

4. 데이터 항목이 무효화 될 수 없었습니다. 이것은 DBA가 때때로 치아를 연마하는 데 영향을 미쳤습니다. 그러나 집행되었다.

그건 그냥 틀렸어 개발자가 처리 할 수없는 NULL경우 큰 문제가 있습니다.

데이터베이스 (전용) 특정 조치를 통해 이러한 공격으로부터 데이터베이스를 보호 할 수 있습니까?

저장 프로 시저가 필요 하지 않으며 pg_query_params 와 같이 인수를 이스케이프하는 함수로 매개 변수화 된 쿼리 를 사용 하십시오 . 물론, 데이터베이스가 세계적으로 기록 가능하거나 클라이언트 역할이 모든 것에 완전히 액세스 할 수 있다면 어쨌든 망할 수 있습니다. 누군가가 와서 클라이언트가하는 일을 깨닫고 나서 5 분 안에 DB를 파괴 (또는 더 심하게 독약 화)시키는 클라이언트를 요리해야합니다.



역할 +1 그들은 이것에 대한 주요 기여자입니다-나는 내 질문에 역할을 포함시키지 않았지만 설정의 일부였습니다. 특히보기에는 고객에게 제안하는 것처럼 제한된 역할이 할당되었습니다. 조회수의 실적에 대한 점입니다. 도메인에는 유효성 검사 테스트가 포함되었으며 범위와 길이가 대부분입니다. data nullable 규칙에 대한 귀하의 의견은이 규칙에 대해 들었던 것보다 훨씬 예의입니다. 이것이 나의 가정이지만 권한이 적절하게 설정 될 것이라고 명시 적으로 밝히지 않았습니다.
Chris Walton

6

나는 당신의 규칙이 당신을 완전히 보호한다고 확신하지 않습니다.

첫 번째 문제는 당신이 그들이 강요 당했다는 사실이지만, 상당한 오버 헤드가 발생할뿐 아니라 완벽한 집행을 본 적이 없다는 것입니다.

두 번째로 내가 읽은 내용은 이와 같은 규칙으로 인해 악용하기가 더 어려워 지지만이를 막지는 못한다는 것입니다. 예를 들어, 뷰에서 동일한 데이터에 액세스 할 수 있으면 테이블에 직접 액세스 할 수없는 것이 실제로 크게 변하지는 않습니다. 클라이언트가 무언가를해야하는 경우에는보기를 용이하게해야하고보기가이를 용이하게하는 경우 공격자는 동일한 기능 / 데이터를 활용할 수 있습니다.

또한 데이터를 업데이트하거나 삭제하는 것이 아니라는 점을 기억하십시오. SQL 인젝션의 취약점 중 하나는 정보 수집이며 뷰 vCustomers 또는 기본 Customers 테이블을 통해 데이터가 다시 전달되는지 여부는 신경 쓰지 않습니다. 당신 일부 약점에서 자신을 보호했을 수도 있지만 전부는 아닙니다. 마찬가지로 클라이언트가 업데이트를 수행 할 수있는 경우에도 트리거를 통해 SQL을 작성하여 트리거를 시작하고 업데이트 할 수 있습니다.

(트리거를 통해 수행되는 모든 업데이트와 관련하여 두 가지를 말할 것입니다. (1)이 내용을 읽을 때 입에서 약간 아 sick으며 (b) 저장 프로 시저가 마음에 들지 않기 때문에 "유지 관리가 용이하지 않고, 테스트가 덜 가능하고, 고도로 결합되어 있으며, 한 공급 업체에 시스템을 잠그고"같은 내용을 기본적으로 말할 수있는 트리거를 사용합니다.)

SQL 문을 실행할 수있는 하나의 구멍 만 있으면 (그리고 이러한 규칙을 막는 규칙을 보지 못함) 공격자는 그 직전의 매우 직관적이지 않은 데이터베이스를 찾을 수 있습니다. 멈추지 말고 속도를 줄이십시오).

여기에서 또 다른 것은 복잡성을 추가하고 (생성하는 오버 헤드뿐만 아니라) 복잡성이 악용 될 수있는 구멍으로 이어진다는 것입니다.

그런 규칙 집합을 만들 수 없다는 말은 아닙니다. 왜 더 귀찮게하겠습니까? 이러한 종류의 공격을 막는 널리 받아 들여지는 방법을 사용하는 것보다 더 번거롭고 신뢰성이 떨어집니다.


내적, 무의식적 가정에 비추어 실제 쿼리를 이해하고 적절하게 응답 한 +1 왜 아키텍처의 관련 설명에서 많은 코드가 생성되는 프로젝트를 진행하고 있으며이 아키텍처의 일부는 데이터베이스 액세스 루틴을 생성하는 방법을 설명합니다. 이러한 생성 된 루틴이 어떤 형태를 취해야하는지 여전히 열려 있습니다.
Chris Walton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.