본문 바로가기
php

[PHP] MySQL How To Prevent SQL Injection #SQL 공격 방지

by bryan.oh 2021. 1. 9.
반응형

Prevent SQL Injection
SQL 공격 방지

 

어떻게 SQL Injection 을 하는지는 아래 글 참고 하시고요.

2021/01/09 - [php] - [PHP] mysqli injection #SQL 공격

 

MySQLi Prepared Statements

Prepared statements 를 사용하여 sql injection 을 방지할 것 입니다.

php 뿐만 아니라 왠만한 언어에서 prepared statements 방식이 있습니다.

대략 동작 방식을 설명하면

  1. 쿼리에 입력될 파라메터 값을 해당 위치에 ?(물음표)로 입력하여 쿼리문을 만듭니다.

  2. ?(물음표)를 데이터 타입에 맞게 파라메터로 바인딩 합니다.

  3. 쿼리를 실행합니다.

 

뭔소리야..

예제로 보는게 고조최고조

 

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] mysqli error / exception 처리 #mysqli_report

MySQL Error 처리 mysqli_report error 를 report 하도록 설정해야 합니다. 개발 시 Debug 용으로는 report 하도록 하고 Release 에서는 report 하지 않거나 file log 를 씁니다. mysqli_report 의 기본값은 MYSQ..

hello-bryan.tistory.com

 

728x90
반응형

댓글