문제

면을 선택하는 행 테이블에서 나는 기본적으로 두 가지 옵션 중 하나를 다음과 같이

int key = some_number_derived_from_a_dropdown_or_whatever
SqlCommand cmd = new SqlCommand("select * from table where primary_key = " + key.ToString());

거나 사용하여 매개변수

SqlCommand cmd = new SqlCommand("select * from table where primary_key = @pk");
SqlParameter param  = new SqlParameter();
param.ParameterName = "@pk";
param.Value         = some_number_derived_from_a_dropdown_or_whatever;
cmd.Parameters.Add(param);

지금,나는 알고있는 첫 번째 방법은 frowned 기 때문에 가능한 sql injection 공격지만,이 경우에는 매개변수가 정수이고 따라서 정말 가능할을 주입하는 악성 코드입니다.

나의 질문은 이것입니다:당신은 옵션을 사용하는 1 에서 생산 코드를 고려하기 때문에 사용하기 때문에 안전의 사용 편의성과 제어에 삽입되는 매개 변수를(위의 같은 경우,또는 매개 변수가 코드를 작성)?또는 당신은 항상 매개 변수를 사용하여 상관없이 무엇인가?은 매개변수를 100%사출 안전한가요?

도움이 되었습니까?

해결책

내 건너 SQL Injection,인수는 너무 잘 알려진에만 집중하면서 SQL 측면의 매개 변수를 대비 매개 변수입니다.

을 보낼 때 SQL 배치 서버에 어떤 배치는 구문 분석하는 것을 이해.처럼 다른 컴파일러,SQL 컴파일러가 생산 AST 에서 텍스트와 그런 다음 운영하는 구문에 나무입니다.궁극적으로 최적화 프로그램을 변환하는 구문으로 실행 트리하고 마지막으로 생산하고 실행 계획 및 그 실제로 실행됩니다.다시 어둠 속에서 나의 1995 년경 그 차이를 만든다면 배치되었 Ad-Hoc query 또는 저장된 절차로,그러나 오늘날 그것은 절대적으로 아무도,그들은 모두 동일합니다.

지금 매개 변수가 차이를 만들은 클라이언트가 보내는 다음과 같은 쿼리 select * from table where primary_key = @pk 보낼 것입니다 정확히 동일한 SQL 텍스트 모든 시간,아무리 어떤 가치입니다.다음엔 무엇이 있는 전체 프로세스 위에서 설명한 단락.SQL 에서 검색 메모리에 대한 실행 계획은 원료,구문 분석되지 않은, 텍스트 그것을 받았(을 기반으로 해시의 다이제스트 입력)하고 발견하는 경우,를 실행하는 계획입니다.는 것을 의미하지 않는 구문 분석,최적화,아무것은 배치가 바로 실행.에 OLTP 시스템에서 실행되는 수백 수천의 작은 요청은 모든 두 번째,이 빠른 경로 만든 거대한 성과 차이입니다.

보내는 경우 쿼리에는 양식 select * from table where primary_key = 1 다음 SQL 야에서는 적어도 구문을 분석하고 이해하는 내부에 텍스트,이 텍스트가 가능성이 새로운 하나,다른 어떤 이전 배치 그것을 본 것(심지어 하나의 문자처럼 12 전체 배치 다릅니다).그런 다음 운영하는 결과는 구문 나무를 시도하라는 프로세스 간단한 Parameterisation.는 경우 쿼리할 수 있 자동 paremeterized,다음 SQL 가능성이 캐시 실행 계획을 위한 다른 쿼리를 실행하는 이전에 다른 pk 값과 재사용하는 계획에 적어도 당신의 쿼리를 필요로하지 않는 것을 최적화하고 당신은 단계를 생략하고 생성하는 실제 실행 계획을 실행합니다.하지만 아무 의미를 달성했는 전체 단락,가장 짧은 경로에 당신을 달성하는 진정한 매개 변수가 있는 클라이언트 쿼리가 있습니다.

으로 볼 수 있습니다 SQL Server,SQL 통계체 성능의 카운터의 서버입니다.카운터 Auto-Param Attempts/sec 표시됩니다 많은 시간을 초당 SQL 는 번역하는 쿼리를 받지 않고 매개변수로 자동 매개 변수가 있는 하나입니다.각 시도 피할 수 있는 경우에 당신이 제대로 매개 변수화 쿼리에서 클라이언트입니다.는 경우에 당신은 또한 당신의 높은 번호 Failed Auto-Params/sec 가 더 악화,그것이 의미하는 쿼리가 전체 주기의 최적화와 실행 계획을 세대입니다.

다른 팁

항상 사용하는 옵션 2)

첫 번째 중 하나 안전에 관한 SQL Injection attacks.

두 번째 지만 지금까지 안전하지만,또한 수행하기 때문에 더 나은 질의 최적화는 더 나은 기회를 만들기 좋은 쿼리 계획을하기 때문에 그것을 위해 쿼리는 모두 같은 시간,예상 매개 변수는 물론입니다.

왜 당신은 피 Option1

도 보이지만 점점에서 이 값 select 요소가 가짜는 HTTP 요청과 포스트들은 그들이 원하는 특정한 필드가 있습니다.귀하의 코드 옵션 1 에 대한 캐릭터/조합(ie.작은 따옴표,대괄호 etc.).

왜 당신이 사용하는 것이 좋 Option2

SQL 쿼리를 엔진의 수 있는 캐싱을 실행 계획 및 관리에 대한 통계 다양한 쿼리합니다.그래서 쿼리를 통합(최 하나의 과정이 될 수 있는 별도의 저장 프로시저)실행 속도에서 장기 실행됩니다.

나는 아직 듣고 예수할 수 있습 납치에 대한 SQL injection.을 볼 때까지 그것을 입증된 그렇지 않으면,나는 그들을 고려에 안전합니다.

Dynamic SQL 지 말아야 안전한 것으로 간주됩니다.심지어는 신뢰할 수 있는 입력,그것은 나쁜 습관입니다.이 포함되어 있 dynamic SQL 에서 저장된 절차;SQL injection 발생할 수 있습니다.

기 때문에 제어할 수 있는 정수 값,그들이 꽤 많은 동일합니다.나는 일반적으로 사용하지 않는 첫 번째 양식,일반적으로,내 허용하지 않는 두 번째 중 하나이기 때문에,나는 일반적으로 허용하지 않 표 액세스 및 사용을 필요로 저장된 절차에 있습니다.고 있지만 당신이 할 수 있는 SP 실행하지 않고 매개 변수를 사용하여 컬렉션은,아직도 사용하는 것이 좋습 SPs parameters:

-- Not vulnerable to injection as long as you trust int and int.ToString()
int key = some_number_derived_from_a_dropdown_or_whatever ;
SqlCommand cmd = new SqlCommand("EXEC sp_to_retrieve_row " + key.ToString()); 

-- Vulnerable to injection all of a sudden
string key = some_number_derived_from_a_dropdown_or_whatever ;
SqlCommand cmd = new SqlCommand("EXEC sp_to_retrieve_row " + key.ToString()); 

참고 하는 옵션이 있지만 1 은 안전 귀하의 경우에는, 무엇 때 일어난 사람을 보고 사용하는 기술을 정수가 아닌 변수 지금 당신은 사람들을 훈련을 사용하는 기술 열려 주입입니다.

참고할 수 있는 적극적으로 강화하는 데이터베이스를 피하 주사는 효과적인 경우에도 귀하의 응용 프로그램 코드를 결함이 있습니다.계정/는 역할을 응용 프로그램을 사용:

  • 스 테이블의 절대적으로 필요
  • 만에 액세스하도록 보기로 절대적으로 필요
  • 을 허용하지 않은 DDL 문을
  • 수 실행은 위생 및 식물위생 사안에 대한 역할 기준
  • Dynamic SQL 에서 SPs 검토해야 합로 절대적으로 필요

개인적으로 난 항상 사용하는 옵션 2 개의 문제로 습관입니다.말:

기 때문에 당신은 강의 변환에서 드롭다운 값을 int,는 일부를 제공 할 것입 보호에 대한 sql injection attacks.그것은 누군가 시도를 주입하는 추가적인 정보에 게재한 정보,C#예외가 발생하려고 할 때 변환 악성 코드 정수 값으로 방해하려 합니다.

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