(PHP 4 >= 4.3.0, PHP 5)
mysql_real_escape_string — mysql_query에서 특수 문자열을 이스케이프하기위해 사용
unescaped_string 된 문자열에서 접속의 현재 문자 집합으로 특수 문자열을 이스케이프하여 mysql_query() 수행시 안전하게 질의할 수 있도록 한다. 이진 데이터를 입력할 경우 이 함수를 사용해야 한다.
mysql_real_escape_string()는 MySQL 라이브러리 함수인 mysql_real_escape_string를 호출하여, 다음의 문자에 백슬래시를 붙인다: \x00, \n, \r, \, ', ", \x1a.
이 함수는 MySQL로 질의를 전송하기 전에 안전하게 데이터를 만들기 위해 항상 사용해야한다.
이스케이프할 문자열.
MySQL 연결. 지정하지 않으면 mysql_connect()로 연 마지막 연결을 사용합니다. 연결이 없으면, 인수 없이 mysql_connect()를 호출하여 연결을 만듭니다. 연결이 성립되지 않으면 E_WARNING 등급의 오류를 생성합니다.
이스케이프된 문자열을 반환하고 에러가 발생하면 FALSE를 반환한다.
Example #1 mysql_real_escape_string() 예제
<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>
Example #2 SQL 인젝션 공격(Injection Attack)의 예
<?php
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);
// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// This means the query sent to MySQL would be:
echo $query;
?>
MySQL로 전송되는 질의:
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
유효한 비밀번호 없이 누구나 접속하여 접근이 가능하다.
Example #3 "Best Practice" 질의
mysql_real_escape_string()은 각 변수에 대해 SQL 인젝션을 방지한다. 이 예제는 Magic Quotes 설정과는 별개로 데이터베이스를 질의하는 "best practice" 방법을 시연한다.
<?php
if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) {
// 접속
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
if(!is_resource($link)) {
echo "서버 접속 실패\n";
// ... 오류를 적절히 기록
} else {
// ON일 경우 magic_quotes_gpc/magic_quotes_sybase 효과 제거
if(get_magic_quotes_gpc()) {
$product_name = stripslashes($_POST['product_name']);
$product_description = stripslashes($_POST['product_description']);
} else {
$product_name = $_POST['product_name'];
$product_description = $_POST['product_description'];
}
// 안전한 질의 만들기
$query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)",
mysql_real_escape_string($product_name, $link),
mysql_real_escape_string($product_description, $link),
$_POST['user_id']);
mysql_query($query, $link);
if (mysql_affected_rows($link) > 0) {
echo "Product inserted\n";
}
}
} else {
echo "Fill the form property\n";
}
?>
SQL 인젝션 공격이 동작하지 않으며 질의가 정확하게 실행될 것이다.
Note: mysql_real_escape_string()을 사용하기 전에 MySQL 접속이 필요하다. 그렇지 않으면 E_WARNING 등급의 에러가 발생되며, FALSE가 반환될 것이다. 만약 link_identifier 가 정의되지 않으면, 최근 MySQL 접속이 사용된다.
Note: magic_quotes_gpc이 활성화되면, stripslashes()가 모든 데이터에 먼저 적용된다. 이 함수를 데이터에 사용하면 이스케이프된 데이터에 중복 처리될 것이다.
Note: 이 함수가 데이터 이스케이프를 위해 사용되지 않으면, 질의는 SQL Injection Attacks으로 취약점이 생기게 된다.
Note: mysql_real_escape_string()는 %와 _를 이스케이프하지는 않는다. LIKE, GRANT, REVOKE와 결합되어 사용되는 와일드카드이기 때문이다.