Prevent SQL Injection
SQL 공격 방지
어떻게 SQL Injection 을 하는지는 아래 글 참고 하시고요.
2021/01/09 - [php] - [PHP] mysqli injection #SQL 공격
MySQLi Prepared Statements
Prepared statements 를 사용하여 sql injection 을 방지할 것 입니다.
php 뿐만 아니라 왠만한 언어에서 prepared statements 방식이 있습니다.
대략 동작 방식을 설명하면
-
쿼리에 입력될 파라메터 값을 해당 위치에 ?(물음표)로 입력하여 쿼리문을 만듭니다.
-
?(물음표)를 데이터 타입에 맞게 파라메터로 바인딩 합니다.
-
쿼리를 실행합니다.
뭔소리야..
예제로 보는게 고조최고조
SELECT
저번 포스팅에서 봤던 코드는 파라메터 u 에 ' or '1'='1 을 입력하면 모든 row 가 조회됐죠.
아래와 같이 prepare 를 사용하면 그런 문제가 발생하지 않습니다.
<?
include_once $_SERVER["DOCUMENT_ROOT"]."/inc/config.php";
$user = $_GET['u'];
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PWD, DB_NAME);
$stmt = $conn->prepare("SELECT * FROM tb_user WHERE userId = ?");
$stmt->bind_param("s", $user);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0)
exit('No rows');
while($row = $result->fetch_assoc()) {
$ids[] = $row['userId'];
$names[] = $row['userName'];
}
var_export($names);
$stmt->close();
mysqli_close($conn);
?>
이 코드에는 파라메터 u 에 ' or '1'='1 을 입력하면 결과는 No rows 가 나옵니다.
bind_param() 에서 첫번째 파라메터는 ? 위치에 들어가는 데이터 타입을 지정해 줍니다.
* Data Types :
- i - Integer
- d - Double
- s - String
- b - Blob
INSERT / UPDATE / DELETE
// 아래 쿼리문만 insert/update/delete 로 바꾸면 같은 동작을 합니다.
$stmt = $conn->prepare("INSERT INTO tb_user (userId, userAge) VALUES (?, ?)");
$stmt->bind_param("si", $_POST['id'], $_POST['age']);
$stmt->execute();
$stmt->close();
userId 는 string , userAge 는 integer 형식으로 들어가야 하기 때문에
bind_param 에 "si" 를 입력하고 그 뒤에 파라메터를 순서대로 입력하면 됩니다.
affected_rows
몇건이 insert/update/delete 되었는지 확인하려면
$stmt->execute(); 후에 ( $stmt->close() 하기 전 )
$stmt->affected_rows 를 사용하면 됩니다.
insert_id
insert 쿼리를 날린 후에 입력된 행의 id (=key, auto increment) 를 가져오려면
마찬가지로 $stmt->execute(); 후에
$conn->insert_id 를 사용하면 됩니다. ( $stmt 가 아니라 $conn 입니다. )
Error 처리
2021/01/09 - [php] - [PHP] mysqli error / exception 처리 #mysqli_report
'php' 카테고리의 다른 글
[Visual Studio Code] PHP Class 변수 Getter, Setter 자동생성 (0) | 2022.04.09 |
---|---|
[PHP] mysqli error / exception 처리 #mysqli_report (0) | 2021.01.09 |
[PHP] mysqli injection #SQL 공격 (0) | 2021.01.09 |
[PHP] 비밀번호 처리. password_hash, password_verify (0) | 2021.01.09 |
[PHP] Login, ajax 로 구현하기 (0) | 2021.01.09 |
댓글