현재 위치: > 최신 기사 목록> PDOSTATEMENT를 결합하는 방법 :: SQL 주입을 방지하기위한 FetchObject 및 준비된 진술

PDOSTATEMENT를 결합하는 방법 :: SQL 주입을 방지하기위한 FetchObject 및 준비된 진술

gitbox 2025-05-29

현대의 PHP 개발에서 보안은 특히 데이터베이스 쿼리를 처리 할 때 우선 순위를 정해야 할 문제 중 하나입니다. SQL 주입은 공격자가 악성 SQL 코드를 주입하여 데이터베이스를 조작 할 수있는 일반적인 공격 방법입니다. 따라서 준비된 진술pdostatement :: fetchobject 방법의 합리적인 사용은 그러한 위험을 효과적으로 예방할 수 있습니다.

PDO와 준비된 진술은 무엇입니까?

PDO (PHP Data Objects)는 PHP가 제공하는 데이터베이스 액세스 추상화 계층으로 일관된 방식으로 여러 다른 데이터베이스에 액세스 할 수 있습니다.
준비된 명령문은 PDO가 제공하는 메커니즘으로, SQL 구조를 먼저 정의한 다음 매개 변수를 바인딩 할 수있는 메커니즘으로, 사용자가 악성 코드를 입력하더라도 SQL로 실행되지 않아 주입 공격을 방지합니다.

예:

 <?php
// 만들다 PDO 예
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'username', 'password');

// 전처리 명세서가있는 쿼리
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $_GET['id']]);

// 결과를 개체로 가져옵니다
$user = $stmt->fetchObject();

if ($user) {
    echo "사용자 이름: " . htmlspecialchars($user->username, ENT_QUOTES, 'UTF-8');
} else {
    echo "사용자는 찾을 수 없습니다。";
}
?>

이 예에서, 자리 표시 자 : ID는 매개 변수를 바인딩하는 데 사용되며 PDO는 SQL 주입을 피하고 탈출 문제를 자동으로 처리합니다.

FetchObject를 올바르게 사용하는 방법?

FetchObject 메소드를 사용하면 쿼리 결과를 객체로 직접 반환 할 수 있습니다. 기본적으로 익명의 STDClass 객체를 반환하지만 데이터를 호스팅하기 위해 사용자 정의 클래스를 지정할 수도 있습니다.

사용자 수업이 있다고 가정합니다.

 <?php
class User {
    public $id;
    public $username;
    public $email;
}
?>

FetchObject를 사용할 때 클래스 이름을 지정하십시오.

 <?php
$stmt = $pdo->prepare('SELECT id, username, email FROM users WHERE id = :id');
$stmt->execute(['id' => $_GET['id']]);

$user = $stmt->fetchObject('User');

if ($user) {
    echo "환영, " . htmlspecialchars($user->username, ENT_QUOTES, 'UTF-8');
}
?>

이것의 장점은 구조가 더 명확하고 나중에 확장되기 쉽다는 것입니다. 예를 들어 논리적 처리를 위해 사용자 클래스에 메소드를 추가 할 수 있습니다.

안전 팁

PDO 및 FetchObject가 사용 되더라도 다음 사항은 여전히 ​​주목해야합니다.

  • 사용자가 입력 한 SQL 문장을 직접 스플릿하지 마십시오.

  • 항상 자리 표시 자 (자리 표시 자 또는 물음표 자리 표시 자)를 사용하고 매개 변수를 바인딩하십시오.

  • htmlspecialchars를 사용하여 XSS 공격을 방지하기 위해 컨텐츠 출력을 웹 페이지로 올바르게 탈출하십시오.

  • 예를 들어 적절한 오류 처리 모드를 설정하십시오.

 <?php
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>
  • 개발 및 생산 환경을 구별합니다. 프로덕션 환경은 데이터베이스 구조가 유출되는 것을 방지하기 위해 오류 메시지를 직접 표시하는 것을 금지해야합니다.

추가 내용 : 쿼리 실패 처리

강력한 시스템은 데이터베이스 오류를 우아하게 처리 할 수 ​​있어야합니다. 예를 들어:

 <?php
try {
    $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
    $stmt->execute(['id' => $_GET['id']]);
    $user = $stmt->fetchObject('User');

    if (!$user) {
        header('Location: https://gitbox.net/not-found');
        exit;
    }

    echo "안녕하세요, " . htmlspecialchars($user->username, ENT_QUOTES, 'UTF-8');
} catch (PDOException $e) {
    error_log($e->getMessage());
    header('Location: https://gitbox.net/error');
    exit;
}
?>

이 예에서는 예외 처리를 통해 쿼리 오류를 포착하고 상황과 같이 친숙한 오류 페이지로 이동합니다.