MySQL-및 SQL 주입
웹 페이지를 통해 사용자 입력을 가져 와서 MySQL 데이터베이스에 삽입하면 다음과 같은 보안 문제로 인해 자신을 활짝 열어 놓을 가능성이 있습니다. SQL Injection. 이 장에서는 이런 일이 발생하지 않도록하는 방법과 스크립트 및 MySQL 문을 보호하는 방법을 설명합니다.
SQL 주입은 일반적으로 사용자에게 이름과 같은 입력을 요청할 때 발생하며 이름 대신 데이터베이스에서 무의식적으로 실행할 MySQL 문을 제공합니다.
사용자가 제공 한 데이터를 신뢰하지 말고 유효성 검사 후에 만이 데이터를 처리하십시오. 일반적으로 이것은 패턴 일치에 의해 수행됩니다. 다음 예에서 사용자 이름은 영숫자 문자와 밑줄 및 8 자에서 20 자 사이의 길이로 제한됩니다. 필요에 따라 이러한 규칙을 수정하십시오.
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) { $result = mysql_query("SELECT * FROM users WHERE username = $matches[0]");
} else {
echo "username not accepted";
}
이 문제를 설명하려면 다음 발췌 부분을 고려하십시오.
// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name = '{$name}'");
함수 호출은 사용자 테이블에서 레코드를 검색해야합니다. 여기서 이름 열은 사용자가 지정한 이름과 일치합니다. 정상적인 상황에서 $ name에는 영숫자 문자와 공백 만 포함됩니다. 하지만 여기에 완전히 새로운 쿼리를 추가하여$name, 데이터베이스 호출이 재앙으로 바뀝니다. 삽입 된 DELETE 쿼리는 사용자의 모든 레코드를 제거합니다.
다행히 MySQL을 사용하는 경우 mysql_query()함수는 단일 함수 호출에서 쿼리 스택 또는 여러 쿼리 실행을 허용하지 않습니다. 쿼리를 스택하려고하면 호출이 실패합니다.
그러나 다음과 같은 다른 PHP 데이터베이스 확장은 SQLite 과 PostgreSQL, 스택 쿼리를 즐겁게 수행하고 하나의 문자열로 제공된 모든 쿼리를 실행하고 심각한 보안 문제를 만듭니다.
SQL 주입 방지
PERL 및 PHP와 같은 스크립팅 언어에서 모든 이스케이프 문자를 현명하게 처리 할 수 있습니다. PHP 용 MySQL 확장은 다음 기능을 제공합니다.mysql_real_escape_string() MySQL에 특별한 입력 문자를 이스케이프합니다.
if (get_magic_quotes_gpc()) {
$name = stripslashes($name); } $name = mysql_real_escape_string($name); mysql_query("SELECT * FROM users WHERE name = '{$name}'");
LIKE Quandary
LIKE 문제를 해결하기 위해 사용자 지정 이스케이프 메커니즘은 사용자가 제공 한 % 및 _ 문자를 리터럴로 변환해야합니다. 사용하다addcslashes(), 이스케이프 할 문자 범위를 지정할 수있는 함수입니다.
$sub = addcslashes(mysql_real_escape_string("%something_"), "%_"); // $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");