PHP에서 PDO 쿼리의 문제점
이미 알고 계시겠지만, SQL 쿼리는 SQL 인젝션에 취약합니다. PDO 확장은 인젝션과 싸우기 위해 만들어졌지만, 기본 설정만으로는 자동으로 방어해주지 않습니다.
예제를 통해 문제를 살펴보겠습니다. 변수가 삽입되는 다음과 같은 쿼리가 있다고 가정해 보겠습니다:
<?php
$sql = "SELECT * FROM users WHERE id=$id";
$res = $pdo->query($sql);
?>
변수가 외부에서, 예를 들어 GET 파라미터로부터 들어온다고 가정해 보겠습니다. 단순화를 위해, 직접 값을 할당해 보겠습니다. 숫자 값이 들어올 것을 기대합니다. 예를 들어 다음과 같습니다:
<?php
$id = 1;
?>
그러나 악의적인 해커는 다음과 같은 값을
전달할 수 있습니다 (role 필드가 있다고
가정합니다):
<?php
$id = '-1 OR role="admin"';
?>
결국, 우리가 원했던 것은 다음과 같은 쿼리였습니다:
<?php
$sql = "SELECT * FROM users WHERE id=1";
$res = $pdo->query($sql);
?>
하지만 실제로 얻은 것은 웹사이트 관리자를 추출하는 다음과 같은 쿼리입니다:
<?php
$sql = "SELECT * FROM users WHERE id=-1 OR role="admin"";
$res = $pdo->query($sql);
?>
이러한 상황을 피하기 위해 PDO에는 prepared statements (준비된 문장)라는 특별한 메커니즘이 마련되어 있습니다. 이것은 다음 강의에서 다루겠습니다.
의도적으로 데이터베이스에 대해 SQL 인젝션을 수행해 보세요.