매개 변수화 된 명령문이 모든 SQL 주입을 중지 할 수 있습니까?


80

그렇다면 왜 여전히 많은 성공적인 SQL 주입이 있습니까? 일부 개발자가 매개 변수화 된 명령문을 사용하기에는 너무 멍청하기 때문에?


6
이것은 절대적으로 끔찍한 대답을 가진 훌륭한 질문입니다 (
제가

적어도 15k 평판이 좋거나 경험이 좋은 사람이이 질문에 귀중한 의견을 추가 할 수 있기를 바랍니다.
Ibu

4
이 주제에 대한 자세한 내용 은 Bill Karwin의 Sql Injection Myths and Fallacies 토크슬라이드 를 참조하십시오. 그는 SQL 인젝션이 무엇인지, 어떻게 이스케이프가 일반적으로 충분하지 않은지, 저장 프로 시저와 매개 변수화 된 명령문이 어떻게 손상 될 수 있는지 설명합니다.
Mike

2
유사한 질문에 대한 Bill Karwin의 답변 도 참조하십시오 . SQL 주입이란 무엇입니까?
Mike

답변:


66

질문에 대한 내 의견에 게시 한 링크는 문제를 매우 잘 설명합니다. 문제가 지속되는 이유에 대한 내 감정을 아래에 요약했습니다.

  1. 막 시작하는 사람들은 SQL 주입에 대해 인식하지 못할 수 있습니다.

  2. 일부는 SQL 인젝션을 알고 있지만 이스케이프가 유일한 솔루션이라고 생각합니다. 에 대한 빠른 Google 검색을 수행하는 경우 php mysql query나타나는 첫 번째 페이지는 mysql_query이스케이프 된 사용자 입력을 쿼리에 삽입하는 예가 있는 페이지입니다. 대신 준비된 진술을 사용하는 것에 대한 언급이 없습니다 (적어도 볼 수는 없습니다). 다른 사람들이 말했듯이 매개 변수 보간을 사용하는 튜토리얼이 너무 많아서 여전히 얼마나 자주 사용되는지는 놀라운 일이 아닙니다.

  3. 매개 변수화 된 명령문이 작동하는 방식에 대한 이해 부족. 어떤 사람들은 그것이 가치를 피하는 멋진 수단이라고 생각합니다.

  4. 다른 사람들은 매개 변수화 된 명령문을 알고 있지만 너무 느리다고 들었으므로 사용하지 마십시오. 나는 많은 사람들이 매개 변수화 된 문장이 얼마나 느린 지 들어 봤지만 실제로 그들 자신의 테스트를하지 않았다고 생각한다. Bill Karwin이 그의 강연에서 지적했듯이, 준비된 진술의 사용을 고려할 때 성능의 차이를 요인으로 거의 사용해서는 안됩니다. 한 번 준비하고 여러 번 실행하는 것의 이점은 보안 및 코드 유지 관리의 개선과 마찬가지로 종종 잊혀진 것처럼 보입니다.

  5. 일부는 모든 곳에서 매개 변수화 된 명령문을 사용하지만 테이블 및 열 이름, 키워드 및 조건부 연산자와 같은 확인되지 않은 값을 보간합니다. 사용자가 다양한 검색 필드, 비교 조건 및 정렬 순서를 지정할 수있는 것과 같은 동적 검색이 이에 대한 대표적인 예입니다.

  6. ORM을 사용할 때 잘못된 보안 감각. ORM은 여전히 ​​SQL 문 부분의 보간을 허용합니다.

  7. 프로그래밍은 크고 복잡한 주제이고 데이터베이스 관리는 크고 복잡한 주제이며 보안은 크고 복잡한 주제입니다. 안전한 데이터베이스 응용 프로그램을 개발하는 것은 쉽지 않습니다. 숙련 된 개발자도 잡힐 수 있습니다.

  8. stackoverflow에 대한 많은 답변이 도움이되지 않습니다. 사람들이 동적 SQL 및 매개 변수 보간을 사용하는 질문을 작성할 때 매개 변수화 된 명령문을 대신 사용하도록 제안하는 응답이 부족한 경우가 많습니다. 몇몇 경우에 저는 사람들이 준비된 진술을 사용하라는 제 제안을 반박했습니다. 일반적으로 허용 할 수없는 성능 오버 헤드 때문에 발생합니다. 나는 이러한 질문의 대부분을 묻는 사람들이 매개 변수화 된 명령문을 준비하는 데 걸리는 추가 몇 밀리 초가 애플리케이션에 치명적인 영향을 미치는 위치에 있다고 진지하게 의심합니다.


65

SQL 공격을 막는 매개 변수화 된 쿼리에 대한 기사에서는 그 이유를 실제로 설명하지 못합니다. 종종 "그렇기 때문에 이유를 묻지 마십시오."라는 경우가 종종 있습니다. 아마도 그들은 스스로를 모르기 때문일 것입니다. 나쁜 교육자의 확실한 신호는 그들이 무언가를 모른다는 것을 인정할 수 없다는 것입니다. 그러나 나는 빗나 갔다. 내가 혼란스러워하는 것이 완전히 이해할 수 있다고 말하면 간단합니다. 동적 SQL 쿼리를 상상해보십시오.

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

따라서 간단한 SQL 삽입은 사용자 이름을 'OR 1 = 1로 입력하는 것입니다. 이것은 효과적으로 SQL 쿼리를 만듭니다.

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

즉, 사용자 이름이 비어있는 모든 고객 ( '') 또는 1 = 1 (부울 인 true) 인 모든 고객을 선택합니다. 그런 다음-를 사용하여 나머지 쿼리를 주석 처리합니다. 따라서 이것은 모든 고객 테이블을 인쇄하거나 원하는 모든 작업을 수행합니다. 로그인하면 관리자가 될 수있는 첫 번째 사용자의 권한으로 로그인합니다.

이제 매개 변수화 된 쿼리는 다음과 같은 코드를 사용하여 다르게 수행합니다.

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("User", username)
parameters.add("Pass", password)

여기서 사용자 이름 및 암호는 입력 된 관련 사용자 이름 및 암호를 가리키는 변수입니다.

이제이 시점에서 여러분은 이것이 전혀 변경되지 않는다고 생각할 수 있습니다. 확실히 Nobody OR 1 = 1 '-과 같은 사용자 이름 필드에 입력하여 효과적으로 쿼리를 작성할 수 있습니다.

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

그리고 이것은 유효한 주장처럼 보일 것입니다. 그러나 당신은 틀릴 것입니다.

매개 변수가있는 쿼리가 작동하는 방식은 sqlQuery가 쿼리로 전송되고 데이터베이스가이 쿼리가 수행 할 작업을 정확히 알고있는 경우에만 사용자 이름과 암호를 값으로 삽입한다는 것입니다. 이는 데이터베이스가 쿼리가 수행 할 작업을 이미 알고 있기 때문에 쿼리에 영향을 미칠 수 없음을 의미합니다. 따라서이 경우 "Nobody OR 1 = 1 '-"의 사용자 이름과 빈 암호를 찾습니다. 이는 false가되어야합니다.

그러나 이것은 완전한 솔루션은 아니며, 여전히 javascript를 데이터베이스에 넣을 수 있기 때문에 XSS 공격과 같은 다른 문제에 영향을 미치지 않기 때문에 입력 유효성 검사를 수행해야합니다. 그런 다음 이것이 페이지에 읽혀지면 출력 유효성 검사에 따라 일반 자바 스크립트로 표시됩니다. 따라서 가장 좋은 방법은 여전히 ​​입력 유효성 검사를 사용하지만 매개 변수가있는 쿼리 또는 저장 프로 시저를 사용하여 SQL 공격을 중지하는 것입니다.


1
이것은 내가 찾던 것에 많은 것을 추가하지만 "입력 유효성 검사"를 위해 무엇을 할 것인지에 대해 더 설명 할 수 있습니까? 또한 쿼리와 함께 발생할 수있는 다른 공격 (예 : XSS)이 있다고 언급했지만 어떻게 발생하는지 설명해 주시겠습니까? 그래서 본질적으로 우리는 어떻게 SQL 인젝션으로부터 완전히 보호 할 수 있을까요? 아니면 모든 유형의 인젝션을보고있는 것일까 요? 감사.
XaolingBao

3
@JosipIvic : 얼마나 많은 사람들이 매개 변수화 된 명령문이 작동하는지 물었을 때, 당신이했던 것처럼 답을 분석하는 사람이 너무 적다는 것은 충격적입니다. 매우 직관적 인 예제와 함께 명확한 설명을 작성해 주셔서 감사합니다.
daOnlyBG

훌륭한. 예를 들어 그들이 말하는 수천 단어를 그립니다!
Drenai

10

좋은 질문입니다. 대답은 결정 론적보다 확률 적이며 작은 예를 사용하여 내 견해를 설명하려고 노력할 것입니다.

SQL 주입 (SQLi)을 피하기 위해 쿼리에서 매개 변수를 사용하거나 매개 변수와 함께 저장 프로 시저를 사용하도록 제안하는 많은 참조가 네트워크에 있습니다. 저장 프로 시저 (예 :)가 SQLi에 대한 마술 지팡이가 아님을 보여 드리겠습니다. 책임은 여전히 ​​프로그래머에게 있습니다.

'Users'테이블에서 사용자 행을 가져 오는 다음 SQL Server 저장 프로 시저를 고려하십시오.

create procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
declare @sql as nvarchar(512)
set @sql = 'select usrID, usrUName, usrFullName, usrRoleID '+
           'from Users '+
           'where usrUName = '''+@name+''' and usrPass = '''+@pass+''''
execute(@sql)

사용자 이름과 비밀번호를 매개 변수로 전달하여 결과를 얻을 수 있습니다. 암호가 자유 텍스트로되어 있다고 가정하면 (이 예제의 단순성을 위해) 일반적인 호출은 다음과 같습니다.

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [dbo].[getUser] 
   @name = 'admin'
  ,@pass = '!@Th1siSTheP@ssw0rd!!'
GO

그러나 여기에는 프로그래머가 저장 프로 시저 내부에서 사용하는 잘못된 프로그래밍 기술이 있으므로 공격자가 다음을 실행할 수 있습니다.

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [TestDB].[dbo].[getUser] 
   @name = 'admin'
  ,@pass = 'any'' OR 1=1 --'
GO

위의 매개 변수는 저장 프로 시저에 인수로 전달되며 마지막으로 실행될 SQL 명령은 다음과 같습니다.

select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = 'admin' and usrPass = 'any' OR 1=1 --'

.. 사용자로부터 모든 행을 다시 가져옵니다.

여기서 문제는 "저장 프로 시저를 만들고 필드를 매개 변수로 검색하도록 전달"원칙을 따르더라도 SQLi가 여전히 수행된다는 것입니다. 이는 저장 프로 시저 내부에 잘못된 프로그래밍 방식을 복사하기 때문입니다. 문제에 대한 해결책은 다음과 같이 저장 프로 시저를 다시 작성하는 것입니다.

alter procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = @name and usrPass = @pass

제가 말하고자하는 것은 개발자가 먼저 SQLi 공격이 무엇인지, 어떻게 수행 할 수 있는지 배우고 그에 따라 코드를 보호해야한다는 것입니다. 맹목적으로 '모범 사례'를 따르는 것이 항상 더 안전한 방법은 아닙니다 ... 그리고 아마도 이것이 우리가 많은 '모범 사례'를 가지고있는 이유입니다.


나는 당신의 요지를 이해할 수 있고 나는 이것에 대해 유죄입니다. 때때로 매개 변수 연결을 사용한 동적 SQL 쿼리 생성이 필요합니다. 내가 그것에 대해 어떻게 제안 하시겠습니까?
TheProvost

@TheProvost 좋은 질문입니다. sp_executesql 고려 : msdn.microsoft.com/en-us/library/ms188001.aspx
Tim

@ 팀 안녕 팀. Im 동적 SQL을 처음 사용합니다. sp_executesql과 EXECUTE (@SqlQuery)의 차이점은 무엇입니까?
TheProvost

2
나는이 게시물에 잘 간단한 예를 설명 생각 : codeproject.com/Tips/586207/... -하지만 기본적으로 EXECUTE (@SqlQuery) 그러나 sp_executesql을 SQL 주입을, 아무것도 허용하지 않습니다 않습니다 (@SqlQuery, ..., ...) 그것을 방지합니다. Microsoft 문서의 예제가 도움이 될 것입니다.
Tim

팀은 ... 솔루션 TheProvost있다) 당신은 동적 SQL의 경우에 ...) sp_executesql을 (@QUERY, @PARAMETERS, @VARS을 사용할 수 있습니다 ...)
안드레아스 Venieris

5

예, 준비된 명령문을 사용하면 적어도 이론적으로 모든 SQL 주입이 중지됩니다. 실제로 매개 변수화 된 명령문은 실제 준비된 명령문이 아닐 수 있습니다. 예를 들어 PDOPHP에서 기본적으로 에뮬레이트하므로 엣지 케이스 공격에 노출됩니다 .

실제 준비된 진술을 사용한다면 모든 것이 안전합니다. 예를 들어 테이블 이름을 준비 할 수 없다는 반응으로 안전하지 않은 SQL을 쿼리에 연결하지 않는 한 적어도.

그렇다면 왜 여전히 많은 성공적인 SQL 주입이 있습니까? 일부 개발자가 매개 변수화 된 명령문을 사용하기에는 너무 멍청하기 때문에?

예, 교육은 여기서 주요 포인트이며 레거시 코드베이스입니다. 많은 튜토리얼은 이스케이프를 사용하며 불행히도 웹에서 쉽게 제거 할 수 없습니다.


1
연결된 답변은 실제로 준비된 진술과 관련이 없습니다.
당신의 상식

1
@YourCommonSense : 매개 변수화 된 쿼리에 관한 것이며 실제 준비가 아닐 수 있지만 사용 된 드라이버에 따라 에뮬레이션됩니다. 그것은 매우 많은 연결 ... 알고하는 것이 중요합니다
kelunik

1
같은 페이지의 다른 답변에는 매우 좋은 댓글이 있습니다. "모든 쿼리가 매개 변수화되면 2 차 주입으로부터도 보호됩니다. 1 차 주입은 사용자 데이터가 신뢰할 수 없다는 사실을 잊습니다. 2 차 주입은 데이터베이스 데이터가 신뢰할 수 없습니다 (원래 사용자가 제공했기 때문에). "
Rodrigo 2015 년

@kelunik 링크 된 대답은 매개 변수가있는 쿼리가 아니라 본질적으로 가짜 라이브러리에 관한 것입니다. 매개 변수화 된 쿼리는 별도의 매개 변수 값과 함께 서버로 전송되는 쿼리입니다.
Panagiotis Kanavos

@PanagiotisKanavos : 그 대답의 내용을 아주 잘 알고 있습니다. 그것은 당신이 사용하는 매개 변수가있는 쿼리가 실제로 준비된 문으로 구현 될 수 있다는 것을 그냥 예 (그리고 꽤 흔한 일)의 ...
kelunik

3

나는 프로그래밍에서 절대적인 것을 피합니다. 항상 예외가 있습니다. 저장 프로 시저와 명령 개체를 적극 권장합니다. 내 배경의 대부분은 SQL Server에 있지만 때때로 MySql을 사용합니다. 캐시 된 쿼리 계획을 포함하여 저장 프로 시저에는 많은 이점이 있습니다. 예, 이것은 매개 변수와 인라인 SQL을 사용하여 수행 할 수 있지만 주입 공격에 대한 더 많은 가능성을 열어 우려를 분리하는 데 도움이되지 않습니다. 내 응용 프로그램은 일반적으로 해당 저장 프로 시저에 대한 실행 권한 만 갖기 때문에 데이터베이스를 보호하는 것이 훨씬 쉽습니다. 직접적인 테이블 / 뷰 액세스 없이는 아무것도 주입하기가 훨씬 더 어렵습니다. 응용 프로그램 사용자가 손상되면 사전 정의 된 것을 정확하게 실행할 수있는 권한 만 있습니다.

내 2 센트.


이것이 질문과 어떤 관련이 있습니까? 저장 프로 시저에 매개 변수를 어떻게 호출하고 전달 하시겠습니까? 문자열 연결을 사용하거나 매개 변수화 된 쿼리를 사용합니까? 게다가-누군가 "동적"쿼리를 생성하기 위해 저장 프로 시저 에서 문자열 연결을 사용한다면 어떨까요? 이 저장 프로 시저가 의미하는 것은 아니다 그냥 있기 때문에 안전하다
파나지오티스 Kanavos

일반적으로 나는 명령 개체를 사용하고 또한 설계 상 "동적 쿼리"실행을 피합니다.
Derek

2

나는 "벙어리"라고 말하지 않을 것이다.

튜토리얼이 문제라고 생각합니다. 대부분의 SQL 자습서, 책, 바인드 매개 변수를 전혀 언급하지 않고 인라인 값으로 SQL을 설명합니다. 이 튜토리얼에서 배우는 사람들은 그것을 올바르게 배울 기회가 없습니다.


2
충분하지 않습니다. 사람들이 프레임 워크 나 일부 orm을 사용하지 않는 이유는 무엇입니까? 멍청한 테스터로 "멍청한 주사"를 테스트하지 않는 이유는 무엇입니까? 때로는 상사가 당신에게 돈을 잘주지 않거나 프로젝트에 대해 X 돈을 지불하고 당신은 돈을 벌기 위해 한 프로젝트에서 다른 프로젝트로, 다른 프로젝트로 이동해야하기 때문입니다. 당신은 더 빠르고 빨라야합니다. 코더가 스트레스를 받고 너무 눌려서 코드가 작동하지만 잘못 작성되었습니다.
jedi

2

대부분의 코드는 보안과 관리를 염두에두고 작성되지 않았기 때문에 기능 추가 (특히 판매 할 수있는 것)와 보안 / 안정성 / 신뢰성 (매출이 훨씬 더 어렵습니다) 사이에서 선택이 주어지면 거의 항상 전자. 보안은 문제가 될 때만 문제가됩니다.


2

매개 변수화 된 명령문이 모든 SQL 주입을 중지 할 수 있습니까?

예, 데이터베이스 드라이버가 가능한 모든 SQL 리터럴에 대한 자리 표시자를 제공하는 한 가능합니다. 대부분의 준비된 진술 드라이버는 그렇지 않습니다. 필드 이름이나 값 배열에 대한 자리 표시자를 찾을 수 없습니다. 그러면 개발자가 연결 및 수동 서식을 사용하여 수동으로 쿼리를 조정하는 작업으로 돌아갈 수 있습니다. 예상 된 결과.

그래서 배열과 식별자를 포함하여 쿼리에 동적으로 추가 할 수있는 대부분의 리터럴을 지원하는 PHP 용 Mysql 래퍼를 만들었습니다.

그렇다면 왜 여전히 많은 성공적인 SQL 주입이 있습니까? 일부 개발자가 매개 변수화 된 명령문을 사용하기에는 너무 멍청하기 때문에?

보시다시피, 실제로 는 바보가 아니더라도 모든 쿼리를 매개 변수화하는 것은 불가능합니다 .


모든 쿼리가 매개 변수화되어 있으면 (사용자 데이터 또는 데이터베이스 데이터에서 가져옴) 가장 많이 득표 한 댓글 ( stackoverflow.com/a/134138/1086511
Rodrigo

나는 당신이 충분히 합리적이라고 생각했기 때문에 당신의 의견을 요청했습니다. 내가 다른 곳에서 읽은 내용이 유지된다면 당신의 방법이 최고라고 생각하지 않습니다. 어쨌든, "일반 도구로는 모든 쿼리를 매개 변수화 할 수 없습니다"를 개선하면 좋을 것입니다.
Rodrigo

"SQL 리터럴"을 식별하는 아이디어에 도달 할 때까지 답변을 읽기 시작했습니다. 이 아이디어는 나에게 옳지 않은 것 같았습니다 (과도한 것 같았습니다). 매개 변수화 된 쿼리가 PHP에서 삽입을 피하는 것이 사실이라면 (아직 연구 중) 다음 단계는 자바 스크립트 삽입을 피하는 것입니다. 그런 다음 귀하의 솔루션을 연구하기 위해 돌아올 것입니다. 또한 postgres를 사용하고 있으며 귀하의 솔루션이 mysql에만 해당합니까?
Rodrigo

좋아, 이제 (다시) 읽고 "모든 쿼리를 매개 변수화하는 것은 불가능하다"는 것이 개선이라고 생각하지 않습니다. MySQL에서는 불가능합니까? PostgreSQL에서도 불가능합니까? 왜? 내 PHP 스크립트 외부에 쿼리가 있습니까? 어디? 식별자로 $ _POST 배열에서 제거하려는 예약어를 의미한다고 생각합니까? 이것은 나에게 갈 길이 아닌 것 같습니다 (물론 직감적으로 내가 틀릴 수도 있습니다). 또한 "결박을 시도 했습니까?"라는 메시지를 이해하지 못했습니다. 무엇을 묶어?
Rodrigo

내가 생각했던 것처럼 웹에서 찾기가 쉽지 않습니다. 가능한 경우 참조를 추가하십시오.
Rodrigo

2

첫 번째 질문에 대한 첫 번째 대답 : 예, 제가 아는 한 매개 변수화 된 쿼리를 사용하면 SQL 삽입이 더 이상 가능하지 않습니다. 다음 질문에 대해서는 확실하지 않으며 그 이유에 대한 의견 만 드릴 수 있습니다.

삽입 할 값과 함께 일부 다른 부분 (일부 논리적 검사에 의존 할 수도 있음)을 연결하여 SQL 쿼리 문자열을 "그냥"작성하는 것이 더 쉽다고 생각합니다. 쿼리를 생성하고 실행하는 것입니다. 또 다른 장점은 SQL 쿼리 문자열을 인쇄 (에코, 출력 등) 한 다음이 문자열을 데이터베이스 엔진에 대한 수동 쿼리에 사용할 수 있다는 것입니다.

준비된 문으로 작업 할 때는 항상 한 단계 이상 더 있어야합니다. 쿼리를 작성해야합니다 (물론 매개 변수 포함). 서버에서 쿼리를 준비해야합니다. 매개 변수를 원하는 실제 값에 바인딩해야합니다. 쿼리에 사용하기 쿼리를 실행해야합니다.

특히 매우 오래 지속되는 것으로 입증되는 일부 "빠르고 더러운"작업에 대해서는 다소 더 많은 작업 (그리고 프로그래밍하기가 그렇게 간단하지 않음)입니다.

친애하는,

상자


2

SQL 주입은 데이터와 코드가 동일한 채널을 통해 제공되고 데이터가 코드로 오인되는 더 큰 코드 주입 문제의 하위 집합입니다. 매개 변수가있는 쿼리는 데이터 및 코드에 대한 컨텍스트를 사용하여 쿼리를 형성하여 이러한 문제가 발생하지 않도록합니다.

일부 특정 경우에는 이것이 충분하지 않습니다. 많은 DBMS에서 저장 프로 시저를 사용하여 SQL을 동적으로 실행할 수 있으므로 DBMS 수준에서 SQL 주입 결함이 발생합니다. 매개 변수가있는 쿼리를 사용하여 이러한 저장 프로 시저를 호출해도 프로 시저의 SQL 삽입이 악용되는 것을 방지 할 수 없습니다. 이 블로그 게시물 에서 또 다른 예를 볼 수 있습니다 .

일반적으로 개발자는 기능을 잘못 사용합니다. 일반적으로 코드는 올바르게 완료되면 다음과 같이 보입니다.

db.parameterize_query("select foo from bar where baz = '?'", user_input)

일부 개발자는 문자열을 함께 연결 한 다음 매개 변수화 된 쿼리를 사용합니다. 이는 실제로 우리가 찾고있는 보안 보장을 제공하는 앞서 언급 한 데이터 / 코드 구분을 만들지 않습니다.

db.parameterize_query("select foo from bar where baz = '" + user_input + "'")

매개 변수가있는 쿼리를 올바르게 사용하면 SQL 주입 공격에 대해 매우 강력하지만 뚫을 수없는 보호를 제공합니다.


1

SQL 주입으로부터 애플리케이션을 보호하려면 다음 단계를 수행하십시오.

1 단계. 입력 제한. 2 단계. 저장 프로 시저와 함께 매개 변수를 사용합니다. 3 단계. 동적 SQL과 함께 매개 변수를 사용하십시오.

http://msdn.microsoft.com/en-us/library/ff648339.aspx 참조


8
저장 프로 시저만으로는 실제로 도움이되지 않습니다. 클라이언트 코드에서와 마찬가지로 저장 프로 시저에서 쿼리 문자열을 동적으로 구성 할 수 있습니다.
Phil Miller

@Fahad 저는 # 2를 "쿼리와 저장 프로 시저에서 매개 변수가있는 문 사용"으로 바꿀 수 있습니다. 매개 변수없이 저장 프로 시저를 사용하는 것은 큰 도움이되지 않는다는 Novelocrat의 의견에 +1.
Matthew

1

준비된 명령문이 웹 응용 프로그램의 자체 코드 전체에서 적절하게 사용 되더라도 데이터베이스 코드 구성 요소가 안전하지 않은 방식으로 사용자 입력에서 쿼리를 생성하면 SQL 주입 결함이 여전히 존재할 수 있습니다. 다음은 @name 매개 변수에 SQL 삽입에 취약한 저장 프로 시저의 예입니다.

CREATE PROCEDURE show_current_orders
(@name varchar(400) = NULL)
AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ‘SELECT id_num, searchstring FROM searchorders WHERE ‘ +
‘searchstring = ‘’’ + @name + ‘’’’;
EXEC (@sql)
GO

응용 프로그램이 사용자가 제공 한 이름 값을 안전한 방식으로 저장 프로 시저에 전달하더라도 프로 시저 자체가이를 동적 쿼리에 직접 연결하므로 취약합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.