SQL 인젝션이 무엇인가요?
SQL 인젝션은 비정상적인 방법으로 웹/앱 서비스를 사용하여 SQL 쿼리에 직접 공격을 가하는 가장 기초적인 서비스 공격방식입니다.
여기에서는 MySQL에서 사용되는 SQL 인젝션을 막는 방법을 서술하고자 합니다.
SQL 인젝션이 왜 발생하나요?
개발자의 보안 인식 결여, 마감 시간에 쫒기다 보니 보안 처리를 하지 않음(...) 등 여러가지 이유가 있습니다.
PHP PDO 등을 사용하면 SQL 인젝션을 충분히 막을 수 있지만,
기존에 사용되는 소스코드나 서비스에는 적용하기가 쉽지 않은게 현실입니다.
시작하기 전에 드리는 말씀...
1. SQL 인젝션 방어 코드에 addslashes를 사용하지 말아주세요. - PHP 설정에 따라 오히려 털릴 수도 있습니다.
2. htmlspecialchars를 사용해도, 인젝션 방어에 그리 큰 도움이 되지 않을 수 있습니다.
3. strip_tags를 사용하지 말아주세요. 태그 싹 날아갑니다... ㅠ...
그럼 시~~~작!
SQL 인젝션을 방어하기 위해선 다음과 같은 함수를 사용하면 큰 도움이 됩니다.
그리고 캐릭터셋은 반드시 UTF-8인게 좋습니다. EUC-KR, CP949를 사용하면 취약점이 생깁니다.
1. 범용적으로 인젝션을 막는 방법
Tip. 게시판 html이나, 검색 질의어, 기타 클라이언트가 사용하기 좋은 다용도의 목적.
<?php
// 1번
mysqli_real_escape_string($링크, '여기에 내용을 집어넣기!');
// 1번 사용이 매번 링크를 넣기 불편하다면...
$link = mysqli_connect('서버주소','아이디','패스워드','데이터베이스 이름');
function sql_escape(String $content){
global $link;
return mysqli_real_escape_string($link, $content);
}
위 처럼 쓰면 일단 다 필터링은 되어서 좋은데, 문제점이 특정 문자만 필터링하려면 어떻게 사용해야할까요?
2. 숫자만 나오게 필터링 하기
만약 숫자만 삽입해야하는데, 임의의 문자가 들어가기 염려스럽다면...
Tip. 휴대폰 번호 작성할 때, 생년월일/주민등록번호 등
<?php
// content를 string으로 두는 이유는,
// int형식으로 설정하는 이유는..
// 만약 휴대폰 전화번호가 010-1234-5678 이라면,
// 10-1234-5678 처럼 저장되기 때문입니다.
function only_number(String $content){
return preg_replace('#[^0-9]#', '', $content);
}
3. 숫자와 영문자만 나오게 필터링하기
만약 숫자와 영문자만 들어가야 한다면..
Tip. 아이디 만들때 주로 사용
<?php
// 내용에 있는 A-Z는 기호에 맞게 수정하시면 됩니다.
function only_alpha_number(String $content){
return preg_replace('#[^a-zA-Z0-9]#', '', $content);
}
4. 한글만 나오게 필터링 하기
만약 한글만 들어가야 한다면...
Tip. 이름 입력
<?php
function only_hangul(String $content){
return preg_replace('#[^가-힣]#', '', $content);
}
번외 - htmlspecialchars 를 써야할 때
<?php
$link = mysqli_connect('서버주소','아이디','패스워드','데이터베이스 이름');
function sql_escape(String $content){
global $link;
return mysqli_real_escape_string($link, $content);
}
$search_text = sql_escape($stx);
$search_query = mysqli_query(
$link,
"SELECT
`title`, `content`
FROM
`books_library`
WHERE
`title` like '%{$search_text}%'
|| `content` like '%{$search_text}%';
"
);
// 검색 과정 처리
// ~~~~~~~~~~~~~
// 검색 과정 처리 끝
?>
<!-- 여러분이 입력한 값을 그대로 반환할 때 (1번) -->
당신의 검색어 : <?php echo htmlspecialchars($stx); ?>
<!-- SQL에 저장 된 값을 그대로 반환할 때 (2번) -->
찾은 내용들 :
<?php
for(~~~~~){
echo "제목 : ".htmlspecialchars($변수['title']);
}
?>
이 작업이 너무 귀찮아요..
PDO를 사용하시면 SQL 인젝션에 대해서 안전합니다.
PDO를 사용하시거나..
라라벨에서 사용하는 데이터베이스 오브젝트화 패키지가 있습니다.
컴포저를 다룰 줄 아시면 쉽게 사용할 수 있는데요.
composer require illuminate/database
저걸로 설치한 뒤,
SIR에 있는 게시물(아래에 링크)을 활용하시면 됩니다.
이상입니다.
'Program > PHP' 카테고리의 다른 글
PHP 청크 업로드 / 파일 분할 업로드 예제 (2) | 2024.02.05 |
---|---|
PHP 기본개념 다지기 (0) | 2022.08.15 |
[그누보드5] 그누보드를 로그인 전용 사이트로 바꾸기 (0) | 2021.12.07 |
[PHP] 네이버 클라우드 SENS용 카카오톡 알림톡 라이브러리 (0) | 2018.12.04 |
[외국어]How to make PHP file? (0) | 2016.10.02 |
댓글