PHP 에서 SQL Injection 방지 쿼리 사용법 두가지 (bind_param, PDO)

프로그래밍/PHP|2022. 8. 30. 11:25
반응형

PHP 에서는 MySQL DB 데이터 입력 또는 조회시 SQL Injection 공격을 막기 위한 방법으로

bind_param 또는 PDO 방식을 사용 할 수 있습니다.

 

 

1. bind_param 사용하기

 

1) INSERT, UPDATE, DELETE

값을 출력하지 않아도 되는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$conn = mysqli_connect($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_NAME);

// 쿼리 준비
$stmt = $conn->prepare("INSERT INTO item (id, itemA, itemB) VALUES (?, ?, ?)");

// 데이터 준비
$id = "hero";
$itemA = "sword";
$itemB = "shield";

// 데이터 바인딩
$stmt->bind_param('sss', $id, $itemA, $itemB); // 대체될 데이터 세개 (하단 '참고' 확인)

// 쿼리 실행
$stmt->execute();

// 연결 종료
$stmt->close();
$conn->close();
?>

* 참고 : 바인딩 할때 변수 데이터 형식을 정의 하게 되는데, 아래 네가지 종료가 있습니다.

i : 정수

s : 문자열

d : double

b : BLOB

 

2) SELECT

값을 출력하는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$conn = mysqli_connect($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_NAME);

// 쿼리 준비
$stmt = $conn->prepare("SELECT * FROM item WHERE id=? or id=?");

// 데이터 준비
$var1 = "hero";
$var2 = "hero2";

// 데이터 바인딩
$stmt->bind_param('ss', $var1, $var2); // 대체될 데이터 두개

// 쿼리 실행
$stmt->execute();

// 모든 행의 결과를 출력
$result = $stmt->get_result();
while ($data = $result->fetch_assoc()) {
    echo $data['id'] . " / " . $data['itemA'] . " / " . $data['itemB'] . "<br>";
}

// 연결 종료
$stmt->close();
$conn->close();
?>

 

 

2. PDO 사용하기

 

1) INSERT, UPDATE, DELETE

값을 출력하지 않아도 되는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME", $DB_USER, $DB_PASSWORD);

//쿼리 준비
$stmt = $pdo->prepare("INSERT INTO item (id, itemA, itemB) VALUES (:id, :itemA, :itemB)");

// 데이터 바인딩
$stmt->bindValue(":id", "hero");
$stmt->bindValue(":itemA", "sword");
$stmt->bindValue(":itemB", "shield");

// 쿼리 실행
$stmt->execute();

// 연결 종료
$stmt->close();
$pdo->close();
?>

 

2) SELECT

값을 출력하는 경우 아래와 같은 코드를 사용 합니다.

<?php
$DB_HOST = "localhost";
$DB_USER = "sysdocu";
$DB_PASSWORD = "12345678";
$DB_NAME = "test";

// DB 연결
$pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME", $DB_USER, $DB_PASSWORD);

//쿼리 준비
$stmt = $pdo->prepare("SELECT * FROM item WHERE id=:id");

// 데이터 바인딩
$stmt->bindValue(":id", "hero");

// 쿼리 실행
$stmt->execute();

// 모든 행의 결과를 출력 (한개의 행 또는 한개의 컬럼 등 가져오는 방식은 추가 검색 권고)
$stmt->setFetchMode(PDO::FETCH_ASSOC);  // 추가 설명 아래 '참고' 확인
while ($row = $stmt->fetch()) {
    echo $data['id'] . " / " . $data['itemA'] . " / " . $data['itemB'] . "<br>";
}

// 연결 종료
$stmt->close();
$pdo->close();
?>

* 참고 : 데이터 출력 방식

fetch(PDO::FETCH_BOTH) - 숫자 인덱스와 명명된 인덱스가 있는 배열 입니다.
fetch(PDO::FETCH_ASSOC) - 행은 명명된 인덱스가 있는 배열입니다. ex) $row['itemA']
fetch(PDO::FETCH_NUM) - 행은 숫자 인덱스가 있는 배열입니다. ex) $row[0]

 

 

반응형

댓글()