최근 지인의 서버에 해킹 시도가 있었다는 이야기를 들었습니다. 해당 서버의 로그를 살펴보니 일반 쿼리가 아닌 신기한 쿼리를 보았습니다. 조사 결과 해당 공격은 SQL 인젝션이었습니다. 이번에는 SQL 인젝션과 이를 예방하는 방법에 대하여 알아보겠습니다.

주의 : 본 게시글은 교육용으로 작성한 게시글입니다. 실제 서버에 공격 기법을 사용하면 불법이며, 민형사상의 책임을 질 수 있습니다.
SQL 인젝션(SQL Injection)
SQL 인젝션은 WAS에서 사용자 입력의 입력값을 제대로 검증하지 않고 SQL 쿼리에 삽입하는 경우 발생하는 보안 취약점입니다. 공격자가 검색창, 로그인 화면 등 입력창에 악의적인 SQL 코드를 주입하면, 원래 의도한 쿼리와 다른 동작을 하게 만들어 데이터베이스를 무단으로 조정할 수 있습니다. 단순하지만 꼭 신경 써야 하는 공격 패턴입니다.
예를 들어 아래와 같은 쿼리가 있습니다.
SELECT *
FROM login_db
WHERE id = '입력값1'
AND password = '입력값2';
공격자가 아래와 같은 데이터를 넣으면 어떻게 될까요?
- 입력값1 = ' OR '1'='1
- 입력값2 = 1234
해당 쿼리는 이렇게 실행됩니다.
SELECT *
FROM login_db
WHERE id = ' ' OR '1'='1'
AND password = '1234';
즉 '1' = '1' 이라는 조건은 항상 TRUE이므로 상황에 따라 모든 계정 정보를 가져올 수 있습니다.
사용 원리
SQL 인젝션은 다음과 같은 원리로 이루어집니다.
- 입력값 주입 : 사용자가 입력하는 값이 그대로 SQL 쿼리에 삽입됩니다.
- 쿼리 조작 : OR, UNION, --(주석), ;(세미 클론) 등 SQL 문법을 이용하여 기존 쿼리와 다르게 작동하도록 합니다.
- 정보 탈취 및 조작 : DB 내 스키마 정보, 테이블 구조, 관리자 계정까지 유출할 수 있습니다.
대표적인 공격 방법은 다음과 같습니다.
- 인증 우회 : 로그인 차단을 무력화
- 데이터 유출 : 계정 정보, 개인정보 등 정보 탈취
- 데이터 조작/삭제 : 주요 테이블 조작 및 삭제로 인한 서비스 마비
- 서버 장악 : DB 계정을 통한 서버 권한 상승
해결 방법
1. 데이터 바인딩 기법
cursor.execute("SELECT * FROM login_db WHERE id = %s AND password = %s", (user, pw))
하나의 쿼리 단위로 저장하는 것이 아닌 쿼리와 데이터를 분리하여 실행합니다.
2. ORM(Object Relational Mapping) 활용
Django, SQLAlchemy 같은 ORM을 사용하여 직접 쿼리를 작성할 일을 줄여 인젝션 위험을 낮춥니다.
3. 입력값 검증
이메일, 숫자, 아이디 등 예상되는 값만 들어올 수 있도록 데이터 내 필터를 설치합니다.
4. DB 권한 최소화
서비스 계정에 불필요한 권한을 주지 말고, DML 권한 정도로 제한합니다.
마지막으로
SQL 인젝션은 가장 오래 되었지만, 강력한 웹 보안 공격입니다. 예방 방법은 명확하고 사용자의 입력값을 항상 의심하는 것으로부터 출발합니다. 개발자로서 보안 방법에 관한 꾸준한 연구와 경각심을 가지도록 합시다.
'컴퓨터 > 컴퓨터 관련 지식' 카테고리의 다른 글
| 디자인패턴 - 디자인패턴(Design Pattern)에 대하여 알아보자 (2) | 2025.05.06 |
|---|---|
| 네트워크 - OSI 7 Layer에 대해 알아보자 (0) | 2025.04.18 |
| 포트포워딩 - 로컬 서버를 외부에 공개해보자 (0) | 2025.04.09 |
| 무선통신 - 2.4GHz / 5GHz 대역이 면허 없이 사용 가능한 이유 (0) | 2024.12.09 |
| 알고리즘 - 빅오 표기법 (Big-O notation) (0) | 2024.09.21 |