복붙노트

[SQL] 매개 변수는 정말 충분히 SQL 삽입을 방지 할 수 있습니까?

SQL

매개 변수는 정말 충분히 SQL 삽입을 방지 할 수 있습니까?

나는 특히 .NET 응용 프로그램에서, SQL 쿼리에 매개 변수를 사용하는 선 (善)에 대한 SO에 여기 내 동료 모두를 전파하고 있었어요. 난 지금까지 SQL 주입 공격에 대한 내성을 부여로 약속하기로 갔어요.

이것이 정말 사실이다하지만 나는 경이에 시작 해요. 매개 변수가있는 쿼리에 대한 성공적인 것입니다 알려진 SQL 주입 공격이 있습니까? 당신이 예를 들어 서버에 버퍼 오버 플로우가 발생 문자열을 보낼 수 있습니까?

이 웹 응용 프로그램이 안전한지 확인 할 수 있도록 물론 다른 고려 사항이다 (사용자 입력을 살균처럼 모든 물건이)하지만 지금은 SQL 주입을 생각하고있다. 나는 특히 MSSQL 2005 년과 2008 년 그들이 내 기본 데이터베이스입니다 이후에 공격에 관심이 있지만, 모든 데이터베이스가 흥미 롭다.

편집 : 나는 매개 변수와 매개 변수가있는 쿼리에 의해 무엇을 의미하는지 명확합니다. 매개 변수를 사용하여 나는 "변수"를 사용하는 대신 문자열에서 SQL 쿼리를 구축하는 것을 의미한다. 그래서 그 대신이 일을 :

SELECT * FROM Table WHERE Name = 'a name'

우리는이 작업을 수행 :

SELECT * FROM Table WHERE Name = @Name

다음 쿼리 / 명령 개체에 @Name 매개 변수의 값을 설정합니다.

해결법

  1. ==============================

    1.자리 표시 자 주사를 방지하기에 충분하다. 당신은 여전히 ​​버퍼 오버 플로우 열려있을 수 있습니다,하지만은 SQL 주입 공격을 완전히 다른 맛이다 (공격 벡터가 SQL 구문하지만 이진 않을 것이다). 전달 된 매개 변수가 모두 올바르게 이스케이프되기 때문에, 공격자가 "라이브"SQL처럼 취급 될 데이터를 전달 할 수있는 방법이 없다.

    자리 표시 자 주사를 방지하기에 충분하다. 당신은 여전히 ​​버퍼 오버 플로우 열려있을 수 있습니다,하지만은 SQL 주입 공격을 완전히 다른 맛이다 (공격 벡터가 SQL 구문하지만 이진 않을 것이다). 전달 된 매개 변수가 모두 올바르게 이스케이프되기 때문에, 공격자가 "라이브"SQL처럼 취급 될 데이터를 전달 할 수있는 방법이 없다.

    당신은 자리 내부 기능을 사용할 수 없으며, 그들이 탈출하고 문자열 리터럴을 인용하고 있기 때문에 당신은 열 또는 테이블 이름으로 자리를 사용할 수 없습니다.

    당신이 당신의 동적 쿼리 내부 문자열 연결의 일부로 매개 변수를 사용하는 경우, 당신은 당신의 문자열을 이스케이프하지 않기 때문에, 주입에 여전히 취약하지만, 그대로 될 것입니다. (예 : 정수) 매개 변수에 대한 다른 유형을 사용하면 안전합니다.

    당신이 security_level 같은 값을 설정하는 데 사용 입력을 사용하는 경우 즉, 말했다, 다음 사람이 바로 자신이 시스템에 관리자 만들 수 있었던 난투. 하지만 그건 그냥 기본적인 입력 검증, 그리고 SQL 주입과는 아무 상관이 없습니다.

  2. ==============================

    2.아니, SQL 인젝션의 위험은 당신이 SQL 쿼리로 확인되지 않은 데이터를 보간 언제든지 여전히 존재한다.

    아니, SQL 인젝션의 위험은 당신이 SQL 쿼리로 확인되지 않은 데이터를 보간 언제든지 여전히 존재한다.

    쿼리 매개 변수는 SQL 구문에서 리터럴 값을 분리함으로써 이러한 위험을 방지하는 데 도움이됩니다.

    'SELECT * FROM mytable WHERE colname = ?'
    

    문제가되지 않으나, 그것이 SQL 값 대신 테이블 명, 컬럼 명, 식, 또는 다른 구문 아니기 때문에 쿼리 매개 변수를 사용할 수없는 동적 SQL 쿼리에 데이터를 보간 다른 목적이있다.

    'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')'
    ' ORDER BY ' + @colname'
    

    그것은 당신이 저장 프로 시저를 사용 또는 응용 프로그램 코드에서 직접 동적 SQL 쿼리를 실행하고 있는지 중요하지 않습니다. 위험은 여전히 ​​존재.

    필요에 따라 이러한 경우의 치료는 고용의 FIEO이다 :

  3. ==============================

    3.는 "매개 변수화 쿼리"의 정의에 대한이 스레드에서 약간의 혼동이있는 것 같습니다.

    는 "매개 변수화 쿼리"의 정의에 대한이 스레드에서 약간의 혼동이있는 것 같습니다.

    이전의 정의를 감안할 때, 많은 링크가 작동 공격을 보여줍니다.

    하지만 "정상"정의는 후자입니다. 그 정의 감안할 때, 나는 작동 모든 SQL 인젝션 공격 모르겠어요. 즉, 하나가없는 것을 의미하지 않는다,하지만 난 그것을보고 아직.

    코멘트에서, 나는 그래서 여기 잘하면 분명있을 것입니다 예를 들어이있어, 충분히 명확하게 자신을 표현하고 있지 않다 :

    이 방법은 SQL 주입에 열려

    exec dbo.MyStoredProc 'DodgyText'
    

    이 방법은 SQL 주입에 열려 있지

    using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
        newParam.Value = "DodgyText";
        .....
        cmd.Parameters.Add(newParam);
        .....
        cmd.ExecuteNonQuery();
    }
    
  4. ==============================

    4.동적 쿼리를 구성하는 데 사용되는 문자열 유형 (VARCHAR, NVARCHAR, 등)의 모든 SQL 매개 변수는 여전히 취약

    동적 쿼리를 구성하는 데 사용되는 문자열 유형 (VARCHAR, NVARCHAR, 등)의 모든 SQL 매개 변수는 여전히 취약

    그렇지 파라미터 형식 변환 (예 INT, 소수, 날짜 등으로) 파라미터를 통해 분사 SQL 어떤 시도를 제거해야

    EDIT : 예를 들어, 파라미터 P1 @ 의도 테이블 이름이

    create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) ) 
    AS
        SET NOCOUNT ON
        declare @sql varchar(512)
        set @sql = 'select * from ' + @p1
        exec(@sql)
    GO
    

    @ P1은 드롭 다운 목록에서 선택되는 경우에는 잠재적 인 SQL 인젝션 공격 벡터이고;

    @ P1은 잠재적 SQL 인젝션 공격 벡터 아닌 다음 개입 사용자의 능력에서 승 / 프로그래밍 공식화되면

  5. ==============================

    5.버퍼 오버 플로우가 SQL 인젝션 아니다.

    버퍼 오버 플로우가 SQL 인젝션 아니다.

    매개 변수가있는 쿼리는 SQL 주입에 대한 안전 보장. 그들은 당신의 SQL 서버의 버그의 형태로 가능한 공격이 아닌 보장하지 않습니다,하지만 아무것도 그것을 보장하지 않습니다.

  6. ==============================

    6.당신이 어떤 식 으로든 형태로 동적 SQL을 사용하거나 사용 권한이 테이블 수준에서해야하기 때문에 형성하는 경우 귀하의 데이터는 안전하지 않습니다. 예는 특정 쿼리의 종류와 주입 공격의 양을 제한하지만, 그 또는 그녀가 시스템에있는 방법을 발견하면 사용자가 얻을 수있는 당신이 액세스하는 내부 사용자 완전히 vunerable있는 액세스가 제한되지 무엇을 그들은하지해야 사기를 저지 또는 판매에 개인 정보를 도용하기 위해. 모든 유형의 동적 SQL은 위험한 방법입니다. 당신이 비 동적 저장 발동을 사용하는 경우 procesdure 수준에서 사용 권한을 설정할 수없고 사용자는 (물론 시스템 관리자는 제외) 발동에 의해 정의되는 것을 제외하고는 아무것도 할 수 없습니다.

    당신이 어떤 식 으로든 형태로 동적 SQL을 사용하거나 사용 권한이 테이블 수준에서해야하기 때문에 형성하는 경우 귀하의 데이터는 안전하지 않습니다. 예는 특정 쿼리의 종류와 주입 공격의 양을 제한하지만, 그 또는 그녀가 시스템에있는 방법을 발견하면 사용자가 얻을 수있는 당신이 액세스하는 내부 사용자 완전히 vunerable있는 액세스가 제한되지 무엇을 그들은하지해야 사기를 저지 또는 판매에 개인 정보를 도용하기 위해. 모든 유형의 동적 SQL은 위험한 방법입니다. 당신이 비 동적 저장 발동을 사용하는 경우 procesdure 수준에서 사용 권한을 설정할 수없고 사용자는 (물론 시스템 관리자는 제외) 발동에 의해 정의되는 것을 제외하고는 아무것도 할 수 없습니다.

  7. ==============================

    7.사출 여기에 데이터 잘림으로 사용 : proc 디렉토리에 저장을 참조 오버 플로우 / 절단을 통해 SQL 주입 특별한 유형에 취약 할하는 것이 가능하다 :

    사출 여기에 데이터 잘림으로 사용 : proc 디렉토리에 저장을 참조 오버 플로우 / 절단을 통해 SQL 주입 특별한 유형에 취약 할하는 것이 가능하다 :

    http://msdn.microsoft.com/en-us/library/ms161953.aspx

  8. ==============================

    8.그냥 매개 변수를 사용하여 쉽게 문자열을 저장하거나 어떤 정책이없는 경우 사용자 이름을 말할 수있는 기억 "; 드롭 테이블 사용자) -"

    그냥 매개 변수를 사용하여 쉽게 문자열을 저장하거나 어떤 정책이없는 경우 사용자 이름을 말할 수있는 기억 "; 드롭 테이블 사용자) -"

    자체 이것은 어떤 피해가 발생하지 않습니다,하지만 당신은 더 나은 장소와 날짜가 다른 물건을 나중에에 검색 예 : 쿠키에 저장된 응용 프로그램 (에에 대한 자세한 사용 방법을 알고있다.

  9. ==============================

    9.당신은 예를 들어 동적 SQL을 실행할 수 있습니다

    당신은 예를 들어 동적 SQL을 실행할 수 있습니다

    DECLARE @SQL NVARCHAR(4000);
    DECLARE @ParameterDefinition NVARCHAR(4000);
    
    SELECT  @ParameterDefinition = '@date varchar(10)'
    
    SET @SQL='Select CAST(@date AS DATETIME) Date'
    
    EXEC sp_executeSQL @SQL,@ParameterDefinition,@date='04/15/2011'
    
  10. from https://stackoverflow.com/questions/306668/are-parameters-really-enough-to-prevent-sql-injections by cc-by-sa and MIT license