일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- csrf
- union sql injection
- blind sql injection
- 과제
- 게시판 만들기
- 문제 풀이
- sql injection
- 로그인
- XSS
- cookie 탈취
- MySQL
- 웹 개발
- php
- 웹 해킹
- 웹개발
- 세션
- css
- Error based sql injection
- file upload
- 증적 사진
- 보안 패치
- lord of sql injection
- Python
- CTF
- Los
- 로그인페이지
- JS
- 보고서
- 모의해킹
- sql injection point
- Today
- Total
Almon Dev
SQL Injection 보안 패치 본문
1. 개요
SQL Injection 이란?
SQL Injection은 사용자가 입력한 값이 SQL 쿼리에 그대로 삽입되는 취약점을 악용하여, 임의의 SQL 문을 삽입하여 실행하는 공격입니다. 이를 통해 데이터베이스에서 무단으로 정보를 조회하거나, 로그인 인증 등을 우회할 수 있습니다.
보안 패치의 목적 및 중요성
이번 보안 패치는 SQL Injection 취약점을 제거하여 데이터베이스의 보안을 강화하는 것을 목표로 합니다. 이를 통해 불법적인 데이터 조회 및 조작을 방지하고, 로그인 인증의 안정성을 확보할 수 있습니다.
Prepared Statement 이란?
Prepared Statement는 SQL 쿼리를 미리 컴파일한 후, 사용자 입력값을 나중에 추가하여 실행하는 방식입니다. 이를 통해 SQL Injection을 방지하고, 성능도 최적화할 수 있습니다.
2. 취약점 분석
SQL Injection 발생 원인
로그인 과정에서 사용자의 입력값을 그대로 SQL 쿼리에 삽입하여 SQL Injection이 발생합니다.
login_proc2.php
....
$id = $_POST["id"];
$pass = $_POST["passwd"];
// 사용자의 id 입력값을 그대로 SQL 쿼리에 삽입
$sql = "select nickname,password from users where user_id='$id';";
$sql_result = runSQL($sql);
....
mysql.php
function runSQL($sql) {
...
$conn = mysqli_connect($host, $id, $password, $dbname);
if (!$conn) {
die("mysql 연결 에러 : ". mysqli_connect_error());
}
$result = mysqli_query($conn, $sql);
if (!$result) {
die("쿼리문 에러 : " . mysqli_error($conn));
}
mysqli_close($conn);
return $result;
}
SQL Injection 예시
ID 입력창에 SQL 쿼리를 삽입하여 Blind SQL Injection이 가능합니다.
1. 참 쿼리를 삽입하여 로그인을 시도합니다.
2. 로그인에 성공하는 것으로 삽입한 SQL 쿼리가 실행되는 것을 확인합니다.
3. id 파라미터에 SQL 쿼리를 삽입해 데이터베이스 명의 첫자리가 a임을 알아냅니다.
3. 보안 패치 적용
수정 코드
Prepared Statement를 사용해 사용자의 입력 값을 문자열로만 취급하도록 수정해 SQL Injection을 방지했습니다.
mysql.php
function sqliConn() {
$host = "localhost";
$id = "root";
$password = "admin1234";
$dbname = "almond";
$mysqli = new mysqli($host, $id, $password, $dbname);
if ($mysqli->connect_error) {
die("mysql 연결 에러: " . $mysqli->connect_error);
}
return $mysqli;
}
여러 페이지에서 사용해도 아이디, 비밀번호 등을 수정하기 편하게 하기 위해 sqliConn 함수를 추가해 mysqli 객체를 반환하도록 하였습니다.
login_proc2.php
....
$id = $_POST["id"];
$mysqli = sqliConn();
$stmt = $mysqli->prepare("select nickname,password from users where user_id=?;");
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result();
....
기존 SQL 쿼리에 id 파라미터의 값을 그대로 삽입하는 방식 대신 SQL 쿼리를 미리 컴파일하고, 사용자 입력 값을 나중에 추가하는 방식으로 변경했습니다.
4. 보안 패치 결과
보안 패치 후 테스트 결과
보안 패치 후 입력값에 SQL 쿼리를 삽입해도 문자열로 취급되어 실행되지 않는 것을 확인했습니다.
1. id 파라미터에 참 쿼리를 삽입합니다.
2. 로그인에 실패하는 것으로 and '1'='1' 참 쿼리가 실행된 것이 아니라 문자열로 취급된 것을 확인합니다.
3. 서버 측 로그 확인 결과 정상적으로 Prepared Statement가 사용되었습니다.
'웹 해킹 > 웹 개발' 카테고리의 다른 글
디렉터리 인덱싱 보안 패치 (0) | 2025.04.04 |
---|---|
Stored XSS 보안 패치 (0) | 2025.04.03 |
게시판 만들기 #10 (게시글 내부에 이미지 추가) (0) | 2025.02.13 |
게시판 만들기 #9 (게시글 검색과 정렬) (0) | 2025.01.31 |
게시판 만들기 #7 (아이디 비밀번호 찾기) (0) | 2025.01.22 |