복붙노트

[SQL] 어떻게 된 PreparedStatement 피하거나 방지 SQL 주입을합니까?

SQL

어떻게 된 PreparedStatement 피하거나 방지 SQL 주입을합니까?

그자는 PreparedStatements 피할 / 방지 SQL 주입을 알고있다. 그것은 어떻게합니까? 자는 PreparedStatements를 사용하여 구성되어 최종 형태의 쿼리 문자열이 될하거나됩니다 것인가?

해결법

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

    1.SQL 인젝션의 문제점은 사용자 입력이 SQL 문장의 일부로서 사용된다는 것이다. 준비된 문을 사용하여 당신은 (SQL 명령의 일부로서가 아닌) 매개 변수의 내용으로 처리하기 위해 사용자의 입력을 강제 할 수 있습니다.

    SQL 인젝션의 문제점은 사용자 입력이 SQL 문장의 일부로서 사용된다는 것이다. 준비된 문을 사용하여 당신은 (SQL 명령의 일부로서가 아닌) 매개 변수의 내용으로 처리하기 위해 사용자의 입력을 강제 할 수 있습니다.

    당신이 당신의 준비된 명령문에 대한 매개 변수로 사용자의 입력을 사용하는 대신 함께 문자열을 결합하여 SQL 명령을 구축하지 않는 경우 준비된 문을 사용하는 경우에도, 당신은 여전히 ​​SQL 인젝션에 취약하다.

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

    2.같은 일을하고 두 가지 방법을 고려 :

    같은 일을하고 두 가지 방법을 고려 :

    PreparedStatement stmt = conn.createStatement("INSERT INTO students VALUES('" + user + "')");
    stmt.execute();
    

    또는

    PreparedStatement stmt = conn.prepareStatement("INSERT INTO student VALUES(?)");
    stmt.setString(1, user);
    stmt.execute();
    

    "사용자"경우 사용자의 입력에서 와서 사용자 입력했다

    Robert'); DROP TABLE students; --
    

    그런 다음 첫 번째 인스턴스에서, 당신은 씻어 버렸어요 될 것입니다. 두 번째, 당신은 안전 할 것 리틀 바비 테이블이 학교에 등록됩니다.

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

    3.의 PreparedStatement는 SQL 주입을 방지하는 방법을 이해하기 위해, 우리는 SQL 쿼리 실행의 단계를 이해할 필요가있다.

    의 PreparedStatement는 SQL 주입을 방지하는 방법을 이해하기 위해, 우리는 SQL 쿼리 실행의 단계를 이해할 필요가있다.

    1. 컴파일 단계. 2. 실행 단계.

    SQL 서버 엔진이 쿼리를 수신 할 때마다,이 단계 아래로 통과 할 수있다,

    장소 홀더가 사용자 데이터로 대체 한 후 (기억, 마지막 쿼리는 아니다 다시 해석 / 컴파일 및 SQL Server 엔진 취급 사용자 데이터 순수 데이터로서가 아니라 구문 분석하거나 다시 컴파일 할 필요가 SQL; 그게의 PreparedStatement의 아름다움입니다.)

    쿼리가 다시 컴파일 단계를 통과하지 않는 경우, 어떤 데이터에 교체 자리는 직접 순수한 데이터로 취급 SQL Server 엔진에 아무런 의미가 없으며된다 쿼리를 실행합니다.

    참고 :이 / 해석에게 쿼리를 이해하는 단계를 분석 한 후 컴파일 단계입니다 구조와 그것에 의미있는 동작을 제공합니다. PreparedStatement의 경우, 쿼리는 한 번만 컴파일 및 캐시 컴파일 된 쿼리를 대체하기 위해 모든 시간을 포착한다 사용자 데이터 및 실행.

    때문에 PreparedStatement의 1 개 회 편집 기능, 그것은 SQL 인젝션 무료입니다 공격.

    여기 예와 자세한 설명을 얻을 수 있습니다 : http://javabypatel.blogspot.in/2015/09/how-prepared-statement-in-java-prevents-sql-injection.html

  4. ==============================

    4.해, PreparedStatement에 사용되는 SQL 드라이버에 미리 컴파일됩니다. 그 시점에서, 파라미터는 리터럴 값과 SQL 아닌 실행 부와 드라이버로 전송된다; 따라서 어떤 SQL은 매개 변수를 사용하여 주입 될 수 없다. 심지어 파라미터 값이 다른 명령문 여러 번 실행할 때자는 PreparedStatements 다른 유익한 부작용 (프리 D + 전용 파라미터를 전송)를 드라이버로 (가정 드라이버 지원을자는 PreparedStatements 해당) SQL 파싱 및 편집 각각을 수행 할 필요가없는 성능 향상 인 매개 변수의 변화를 시간.

    해, PreparedStatement에 사용되는 SQL 드라이버에 미리 컴파일됩니다. 그 시점에서, 파라미터는 리터럴 값과 SQL 아닌 실행 부와 드라이버로 전송된다; 따라서 어떤 SQL은 매개 변수를 사용하여 주입 될 수 없다. 심지어 파라미터 값이 다른 명령문 여러 번 실행할 때자는 PreparedStatements 다른 유익한 부작용 (프리 D + 전용 파라미터를 전송)를 드라이버로 (가정 드라이버 지원을자는 PreparedStatements 해당) SQL 파싱 및 편집 각각을 수행 할 필요가없는 성능 향상 인 매개 변수의 변화를 시간.

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

    5.나는 그것이 문자열이 될 것 같아요. 그러나 입력 매개 변수는 데이터베이스 및 해당 캐스트로 전송됩니다 / 전환은 실제 SQL 문을 만들기 전에 적용됩니다.

    나는 그것이 문자열이 될 것 같아요. 그러나 입력 매개 변수는 데이터베이스 및 해당 캐스트로 전송됩니다 / 전환은 실제 SQL 문을 만들기 전에 적용됩니다.

    당신에게 예를 제공하기 위해, 그것은 시도하고 CAST는 / 변환 작동하는지 볼 수 있습니다. 그것이 작동하는 경우, 그것의 마지막 문장을 만들 수 있습니다.

       SELECT * From MyTable WHERE param = CAST('10; DROP TABLE Other' AS varchar(30))
    

    숫자 매개 변수를 받아들이는 SQL 문을 예를보십시오. 지금, (수치 파라미터로서 허용 숫자 콘텐츠) 문자열 변수를 전달하려고. 그것은 어떤 오류가 발생합니까?

    이제 (숫자 매개 변수로 허용되지 않는 컨텐츠) 문자열 변수를 전달하려고합니다. 무슨 일이 일어 나는지?

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

    6.준비된 문은 더 안전합니다. 그것은 지정된 형식으로 매개 변수를 변환합니다.

    준비된 문은 더 안전합니다. 그것은 지정된 형식으로 매개 변수를 변환합니다.

    예 stmt.setString (1 사용자)와; 문자열에 사용자 매개 변수를 변환합니다.

    그 허용하지 않습니다 준비된 문을 사용하여 : 매개 변수는 실행 명령이 포함 된 SQL 문자열을 포함한다고 가정하자.

    그것은 그에게 메타 문자 (일명, 자동 변환)를 추가합니다.

    이것은 더 안전합니다.

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

    7.SQL 주입 : 사용자가 SQL 문을의 일부가 될 수있는 입력 뭔가 기회가있을 때

    SQL 주입 : 사용자가 SQL 문을의 일부가 될 수있는 입력 뭔가 기회가있을 때

    예를 들면 :

    문자열 쿼리 = "INSERT INTO 학생의 VALUES ( '"+ 사용자 + "')"

    때 사용자 입력 "로버트 '); DROP 표 학생; - "입력, 그것은 SQL 인젝션 원인

    이 방법은 준비된 문장 방지?

    문자열 쿼리 = "INSERT INTO 학생의 VALUES ( '"+ "이름"+ "')"

    parameters.addValue ( "이름", 사용자);

    => 때 사용자 입력을 다시 "로버트 '); DROP 표 학생; - "입력 문자열 리터럴 값으로 드라이버에 미리 컴파일 나는이 같은 주조 할 수있다 생각한다 :

    CAST ( '로버트'); DROP 표 학생; - 'VARCHAR AS (30))

    마지막에 그래서, 문자열은 문자 그대로 테이블에 이름으로 삽입됩니다.

    http://blog.linguiming.com/index.php/2018/01/10/why-prepared-statement-avoids-sql-injection/

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

    8.PreparedStatement의 :

    PreparedStatement의 :

    전체 빠른 실행 및 일괄 동일한 SQL 문장을 재사용 할 수있는 능력에 대한 SQL 문 리드 1) 미리 컴파일 및 DB 측 캐싱.

    따옴표 및 기타 특수 문자 이스케이프 내장하여 SQL 주입 공격의 2) 자동 방지. 이 값을 설정하기 위해 PreparedStatement로하는 setXXX () 방법을 사용하는 것이 필요합니다.

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

    9.이 글에서 설명하고있는 바와 같이 여전히 문자열을 연결하는 경우, PreparedStatement의 혼자 도움이되지 않습니다.

    이 글에서 설명하고있는 바와 같이 여전히 문자열을 연결하는 경우, PreparedStatement의 혼자 도움이되지 않습니다.

    예를 들어, 하나의 악의적 인 공격자는 여전히 다음과 같은 작업을 수행 할 수 있습니다 :

    당신이 바인드 매개 변수를 사용하지 않는 경우 SQL하지만, 심지어 JPQL 또는 HQL뿐만 아니라이 손상 될 수 있습니다.

    SQL 문을 만들 때 결론은, 당신은 문자열 연결을 사용해서는 안됩니다. 그 목적을 위해 전용 API를 사용합니다 :

  10. from https://stackoverflow.com/questions/1582161/how-does-a-preparedstatement-avoid-or-prevent-sql-injection by cc-by-sa and MIT license