1

PHP - 게시판 제작 8 - 취약점 고치기

PHP - 게시판 제작 8 - 취약점 고치기

노아의 블로그

    목차
반응형

게시판의 read 페이지를 SQL Injection 공격으로 ID 와 PASSWORD 를 알아냈습니다.

원인은 무엇일까요. 

 

일단 안에서 만들어지는 쿼리문을 출력해봅시다.

사용자가 입력한 정보가 그대로~ 그냥 직빵으로 꽂혀서 쿼리문이 만들어 지고 있습니다.

그래서. 쿼리문의 변조가 가능하지요.

 

이 취약점을 해결하자면...너무 간단한 한 가지의 방법이 존재합니다.

 

바로 Prepared Statement를 사용해서 쿼리문을 제작하는 것 입니다.

 

지금 같은 경우에는, 사용자의 입력과 쿼리문의 생성이 동시에 실행이 되고 있습니다. 그러므로 사용자 입력이 쿼리문과 섞이면 언제든지 조작이 가능한 상태인거죠.

 

Prepared Statement는 이와 달리 사용자의 입력과 쿼리문의 생성을 분리한 것 입니다.

즉, 쿼리를 먼저 생성합니다. 그 다음 사용자의 입력을 넣습니다.

쿼리를 먼저 생성해놓으니까 사용자의 입력이 아무 소용이 없는 것 입니다.

 

자세한 설명은 인터넷이나 다른 글에 있으니 참고하시구요. 

 

핵심은 입력과 생성의 분리라고 생각하시면 됩니다.

 

이제 적용을 해 봅시다.

 

<?php include "../connect.php"; ?>
<?php 
$bno = $_GET['bno'];
$sql = "select * from board where bno = ?";
$stmt = $conn->prepare($sql); //1
$stmt->bind_param('i',$bno); //2
$stmt->execute(); //3
$result = $stmt->get_result(); //4
if($result){
$row = $result->fetch_assoc();
        echo "title : " . $row['title']; 
        echo "<br>";
        echo "content : " . $row['content'];
        echo "<br>";
        
        echo "<a href = 'update.php?bno=$bno'>modify</a>";
        echo "<br>";
        echo "<a href = 'delete.php?bno=$bno'>delete</a>";

}

?>

 

1번은 preparedstatement 로 쿼리문을 만든것이구요.

2번은 만들어진 쿼리문에 bno를 넣습니다.

3번은 실행을 하구요. 

4번은 결과를 불러옵니다.

 

그러면 아까와 같이 SQL Injection 공격을 시도해 봅시다. 

먼저 공격할때 기본적으로 하는 and 1=1을 입력합시다.

???? 당황스럽습니다. 이렇게 보안이 무너지는걸까요?

이번에는 union injection 공격을 해 봅시다.

아무것도 나오지 않습니다. 근데 왜 아까전에는 나왔을까요? 이는 코드를 보면 알 수 있습니다.

6번 줄에 bind_param. 파라미터를 만들어진 쿼리문에 넣는다는 뜻 입니다.

어떤 타입을? i를...즉 integer(정수)를. 

하지만 bno에 들어가 있는 값은? 15 and 1 = 1입니다. 이것은 숫자가 아니라 숫자와 문자가 혼합된 문자입니다.

그래서 문자열을 모두 버려버리고 15만 남겨서 

select * from board where bno = 15; 이렇게 만들어지는겁니다.

결국은 and 1 = 1은 실행되지 않았습니다. 

의문이 생기신다면 1 = 2를 넣어보세요. 이것은 문법적으로 false인데 잘 출력이 나옵니다. 즉 무효 처리가 된것이죠!

 

 

prepared statement를 이용해서 보안을 강화를 마쳤습니다.

축하드립니다. 이제 게시판에는 sql injection 공격을 할 수 없습니다.

 

반응형