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 데이터베이스 확장은 SQLitePostgreSQL, 스택 쿼리를 즐겁게 수행하고 하나의 문자열로 제공된 모든 쿼리를 실행하고 심각한 보안 문제를 만듭니다.

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}%'");