[sql,db] prepared statement는 sql injection(인젝션)을 막을 수 있는가?

안녕하세요. 개발자 드리머즈입니다.


db query시, prepared statement(준비된 명령문)를 사용하면 sql injection에 대해 안전하다고 하여 관련 자료를 찾아봤습니다.

w3schools.com에 아래와 같은 설명이 있습니다.


출처 : https://www.w3schools.com/php/php_mysql_prepared_statements.asp

Prepared statements are very useful against SQL injections.


Prepared Statements and Bound Parameters

A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency.

Prepared statements basically work like this:

  1. Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?"). Example: INSERT INTO MyGuests VALUES(?, ?, ?)
  2. The database parses, compiles, and performs query optimization on the SQL statement template, and stores the result without executing it
  3. Execute: At a later time, the application binds the values to the parameters, and the database executes the statement. The application may execute the statement as many times as it wants with different values

Compared to executing SQL statements directly, prepared statements have three main advantages:

  • Prepared statements reduces parsing time as the preparation on the query is done only once (although the statement is executed multiple times)
  • Bound parameters minimize bandwidth to the server as you need send only the parameters each time, and not the whole query
  • Prepared statements are very useful against SQL injections, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur. 


번역해보면..

준비된 명령문은 SQL 인젝션 예방에 아주 유용하다.

준비된 명령문과 묶인? 파라미터

준비된 명령문은 같은(또는 비슷한) SQL문을 고효율로 반복적으로 실행하기 위해 사용된다.

준비된 명령문은 기본적으로 이렇게 동작한다:


1. 준비 : SQL 문장 템플릿이 만들어지고 데이터베이스로 보내진다. 어떤 값들은 명시되지 않은채 남겨지고, 파라미터("?"라고 이름 붙여진)라고 불린다. 예: INSERT INTO MyGuests VALUES(?, ?, ?)

2. 데이터베이스는 SQL 문장 템플릿를 분석, 컴파일 그리고 쿼리 최적화하고, 결과를 실행하지 않고 저장한다.

3. 실행 : 나중에, 어플리케이션은 값들을 파라미터에 넣고, 데이터베이스는 그 문장을 실행한다. 어플리케이션은 다른 값들로 원하는 만큼 많이 그 문장을 실행할 수 있다.


SQL 문장을 바로 실행하는 것과 비교했을 때, 준비된 명령문은 3개의 주요 장점이 있다:

1. 준비된 명령문은 (비록 명령문이 여러 번 실행되더라도)쿼리에 대한 준비가 오직 한번만 수행되기에 분석 시간을 감소시킨다.

2. 묶인 파라미터는 매번 파라미터만 보내면 되고 전체 쿼리문을 보낼 필요가 없기에 서버의 대역폭(사용량)을 최소화 시킨다.

3. 준비된 명령문은 SQL 인젝션 예방에 아주 유용한데 왜냐하면 (추후에 다른 프로토콜에 의해 전송되는) 파라미터 값은 제대로 이스케이프 처리될 필요가 없다. 만약 원본 쿼리문 템플릿이 외부 입력에서 만들어지지 않는다면, SQL 인젝션은 발생할 수 없다.


서버의 php파일에

sql 쿼리문이 아래와 같이

INSERT INTO MyGuests VALUES(?, ?, ?)

고정되어 있고 외부의 입력으로는 이 템플릿을 변경할 수 없다면,

SQL 인젝션은 발생할 수 없다고 합니다.

보통 그렇게 하는 것 같습니다.


제가 짠 코드를 생각해봐도,

?에 해당하는 파라미터에 들어갈 값만 외부의 입력에서 오고

이것을 제외한 원본 sql 쿼리 템플릿은 고정되어 있으니까요.


SQL인젝션은 걱정 안해도 되겠네요.

작성자

Posted by 드리머즈

관련 글

댓글 영역