프로필카테고리질문하기
로그인 계정 만들기

mysql - SQL 인젝션 공격 방어 방법

04 개월 전

PHP mysql에서 SQL 인젝션 공격은 무엇이고 어떻게 막을 수 있나요?

답변하기 의견 추가
의견 (0)
더 많은 의견 보기

답글 (1)

SQL 인젝선은 공격자가 악의적인 SQL 선언을 만들어 데이터베이스 서버를 조작할 수 있는 공격을 의미해요.

SQL 인젝션은 가장 흔하고 가장 위험한 웹 어플리케이션 취약점 중 하나에요.

SQL 인젝션 방법

SQL 인젝션 공격을 막기 위해서는 어떻게 SQL 인젝션을 하는지 알아야겠죠.

웹 어플리케이션이 사용자의 입력 값을 SQL 선언에 바로 포함시키는 경우 SQL 인젝션 공격이 일어날 수 있어요.

예를 들어 다음의 코드를 보세요:

$username = $_POST["username"]; $password = $_POST["password"]; $mysqli->query("SELECT * FROM users WHERE username='{$username}' AND password='{$password}'");

위의 코드는 사용자로부터 아이디와 비밀번호를 입력받아서 일치하는 행을 선택하고 있어요.

그런데 위의 코드는 공격자가 악의적인 입력 값을 제출할 수 있기 때문에 SQL 인젝션으로부터 취악해요.

예를들어 공격자가 유저네임에 admin, 패스워드에 password' OR 1=1 -- 을 입력하면 이렇게 되겠죠:

SELECT id FROM users WHERE username='admin' and password='password' OR 1=1 --'

이 방법으로 비밀번호를 입력하지 않고 로그인 할 수 있어요.

SQL 인젝션으로 할 수 있는 것들

공격자가 인증을 건너뛸 수 있어요.

공격자가 데이터를 수정하거나 삭제할 수 있어요. 심지어 테이블 전체를 삭제하는것도 가능하죠.

공격자가 특정 데이터를 조회하거나 심지어 완전히 데이터베이스 전체를 빼낼 수도 있어요.

만약 데이터베이스 서버가 운영 체제의 명령을 실행할 수 있도록 만들어진 경우 그것보다 더 나쁜 일이 일어날 수도 있어요.

SQL 인젝션 방어 방법: 준비된 선언

SQL 인젝션이 위험하다는 것은 알았으니 이제 어떻게 방어하는지 알아야겠죠.

SQL 인젝션을 방어하기 위해 가장 좋은 방법은 prepared statement (준비된 선언) 를 사용하는 방법이에요.

PDO 또는 MySQLi 중 하나로 준비된 선언을 사용할 수 있어요. 두 개의 차이점에 대해서는 MySQLi와 PDO 중 어떤걸 쓰는게 좋나요? 질문을 참고하세요.

// PDO 방법 $username = $_POST["username"]; $password = $_POST["password"]; $pdo = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'user', 'password'); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $st = $pdo->prepare('SELECT * FROM users WHERE username=:username AND password=:password'); $st->bindParam(':username', $username); $st->bindParam(':password', $password); $st->execute(); var_dump($st->fetchObject());// MySQLi 방법 $username = $_POST["username"]; $password = $_POST["password"]; $mysqli = new mysqli('localhost', 'username', 'password', 'testdb'); $st = $mysqli->prepare('SELECT * FROM users WHERE username=? AND password=?'); $st->bind_param('s', $username); $st->bind_param('s', $password); $st->execute(); $result = $st->get_result(); var_dump($result->fetch_object());
SQL 인젝션 방어 방법: 이스케이프

이 방법 보다는 준비된 선언을 더 추천해요.

그래도 정말 정말 이스케이프를 사용하고 싶다면 여기에 mysqli_real_escape_string 함수를 사용하는 방법이 있어요.

$username = $mysqli->real_escape_string($_POST["username"]); $password = $mysqli->real_escape_string($_POST["password"]); $mysqli->query("SELECT * FROM users WHERE username='{$username}' AND password='{$password}'");
의견 추가
의견 (0)
더 많은 의견 보기

정보

업보트
1
질문됨
4 개월 전
최근 활동
4 개월 전

카테고리

PHPMySQL