프로그래밍/PHP

php 인젝션 방어 mysql_real_escape_string

p-a-r-k 2017. 7. 12. 15:47
반응형

mysql_real_escape_string
 SQL 명령문에 사용되는 문자열에서 특수 문자를 회피한다.


mysql_query() 에 안전하게 입력시키기 위하여 접속된 현재 문자 셑을 고려하여, 회피되지 않은 문자열에서 특수 문자를 회피한다.
 바이너리 데이터가 삽입된다면, 이 함수가 반드시 사용되어야 한다.
이미 회피된 데이터에 이 함수를 사용하면 데이터를 두번 회피할 것이다.

이 함수는 \x00, \n, \r, \, ', " and \x1a 등의 문자앞에 백슬래쉬(\)를 추가하는 MySQL의 라이브러리 함수라고 불린다.
이 함수는 약간의 예외를 제외하고 MySQL에 질의를 보내기 전에 데이터를 안전하게 만들기 위해 항상 사용되어져야 한다.
이 함수는 %와 _를 회피하지 않는다.
이것들은 LIKE, GRANT, REVOKE와 결합된 MySQL의 임의 문자 기호이다.


<?php
 $link = mysql_connect( 'mysql_host', 'mysql_user', 'mysql_password' )
   OR die( mysql_error() );
 $query = sprintf( "SELECT * FROM users WHERE user='%s' AND password='%s'",
   mysql_real_escape_string( $user ),
   mysql_real_escape_string( $password ) );
 ?>


<?php
 /* SQL Injection Attack */
 $query = "SELECT * FROM users WHERE user='{ $_POST[ 'username' ] }' AND password='{ $_POST[ 'password' ] }'";
 mysql_query( $query );
 // We didn't check $_POST[ 'password' ]
 $_POST['username'] = 'aidan';
 $_POST['password'] = "' OR ''='";
 echo $query;
 ?>


// output: 이것은 일치하는 패스워드 없이 누구든 허용할 것이다.
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

다음 예제는 각 변수 주위에 mysql_real_escape_string() 함수를 사용하여 SQL 주입을 막는다.
질의는 올바르게 실행될 되고, SQL 주입 공격을 받지 않을 것이다.


<?php
 function quote_smart( $value )
 {
   // Stripslashes
   if ( get_magic_quotes_gpc() ) {
    $value = stripslashes( $value );
   }
   // Quote if not a number or a numeric string
   if ( !is_numeric( $value ) ) {
    $value = "'" . mysql_real_escape_string( $value ) . "'";
   }
   return $value;
 }
 $link = mysql_connect( 'mysql_host', 'mysql_user', 'mysql_password' )
   OR die( mysql_error() );
 $query = sprintf( "SELECT * FROM users WHERE user=%s AND password=%s",
   quote_smart( $_POST[ 'username' ] ),
   quote_smart( $_POST[ 'password' ] ) );
 mysql_query( $query );
?>
반응형