Language/php

SQL 인젝션 방지, htmlspecialchars(), isset()

잘먹는 개발자 에단 2025. 1. 31. 15:35

1. SQL 삽입공격이란?

 

SQL 삽입 공격은 사용자가 입력한 데이터가 SQL 쿼리문제 직접 포함되면서 발생하는 보안 취약점이다.

공격자가 악의적인 SQL 코드를 입력해서 db데이터를 조회하거나 삭제할 수 있다.

 

SQL 삽입 공격에 취약한 코드 예시

$name = $_GET['name']; // 사용자의 입력을 그대로 사용한다. 보안에 취약하다.
$sql = "SELECT id, name, email FROM users WHERE name = '$name'";

이러한 경우에 사용자가 만약에 

' OR '1'='1 

을 입력했다. 그러면

SELECT id, name, email FROM users WHERE name = '' OR '1'='1'

뒤에 항상 참인 조건을 넣어서 users 테이블의 모든 데이터가 조회되게 된다.

 

 

2. 그렇다면 SQL 삽입 공격을 방지하려면 어떻게 해야할까?

- 준비된 쿼리 Prepared Query + 바인딩 (bind_param()) 을 사용해야한다.

- htmlspecialchars()로 XSS 공격을 방어한다.

- isset()으로 입력값을 검증한다.

 

** htmlspecialchars()
- 입력폼에 이런거 <script>위험한 js코드</script> 넣는 애들을 위해서 써야한다.

- XSS 공격 방어를 위해 HTML 태그를 무력화한다.

- echo htmlspecialchars($name)을 한다면 출력결과는 아래와 같다. script가 실행되지 않고 단순한 텍스트로 표시된다. 

&lt;script&gt;alert('Hacked!');&lt;/script&gt;

 

 

** isset()

- 변수가 존재하는지 확인하는 함수

- 입력값이 설정되지 않았을 때. 예를 들어서 $_GET['name']이 없을 때 에러를 방지한다.

if (isset($_GET['name'])) {
    $name = $_GET['name'];
    echo "이름: " . $name;
} else {
    echo "이름을 입력하세요!";
}

 

 

 

** 슬프게도 mysql_query()에서는 준비된 쿼리를 사용할 수 없다.

- mysql_query() 는 단순한 SQL 실행함수로, 변수 바인딩 기능이 없다.

즉, Prepared Statements 준비된 쿼리와 bind_param() 을 지원하지 않는다. 

따라서, SQL Injection 공격에 취약할 수 있다. 

 

때문에 mysqli나 pdo 사용이 권장된다.