SQL 인젝션이란 무엇인가?
SQL 인젝션(SQL Injection)은 대표적인 웹 해킹 기법 중 하나입니다. 웹 페이지의 입력 폼을 통해 악성 코드를 삽입하여 데이터베이스를 조작하거나 파괴하는 코드 인젝션(code injection) 기술로, 해커가 데이터베이스 내부의 민감한 정보에 접근할 수 있게 만드는 심각한 보안 취약점입니다.
SQL 인젝션의 주요 원인은 사용자 입력값을 충분히 검증하지 않고 SQL 쿼리에 그대로 전달하는 것입니다. 이렇게 되면 공격자는 쿼리 구조를 조작해 데이터베이스 안의 데이터를 마음대로 열람하거나 변경할 수 있습니다.
SQL 인젝션 공격 예시
학생 정보를 담은 테이블이 있다고 가정해 보겠습니다. 각 학생은 자신의 학번(student id)을 입력하여 본인의 정보만 조회할 수 있도록 SQL 쿼리가 설계되어 있습니다.
그런데 만약 학생이 학번 입력란에 "12345 or 1=1"이라고 입력하면 어떻게 될까요? 이 입력값은 다음과 같은 쿼리로 변환됩니다.
SELECT * FROM Students WHERE id==12345 or 1=1
위 쿼리에서 1=1은 항상 참(true)이기 때문에, WHERE 조건이 무력화됩니다. 그 결과 해당 학생뿐만 아니라 다른 학생들의 레코드까지 모두 반환됩니다. 즉, 타인의 데이터가 노출되며 해커에 의해 악용될 위험에 그대로 놓이게 됩니다.
SQL 인젝션 예방 방법: 플레이스홀더(Placeholder) 사용
SQL 인젝션을 막는 가장 기본적인 방법은 사용자 입력값을 쿼리에 직접 연결하지 않고, 이스케이프 처리된 매개변수 형태로 전달하는 것입니다. Python의 MySQL 커넥터(mysql.connector) 모듈은 쿼리 값을 안전하게 이스케이프할 수 있는 방법을 제공하며, 이때 플레이스홀더 %s를 사용합니다.
예를 들어, 다음과 같은 "MyTable" 테이블이 있다고 가정합니다.
+----------+---------+-----------+------------+ | Name | Class | City | Marks | +----------+---------+-----------+------------+ | Karan | 4 | Amritsar | 95 | | Sahil | 6 | Amritsar | 93 | | Kriti | 3 | Batala | 88 | | Khushi | 9 | Delhi | 90 | | Kirat | 5 | Delhi | 85 | +----------+---------+-----------+------------+
예제 코드
import mysql.connector
db=mysql.connector.connect(host="your host", user="your username", password="your password", database="database_name")
cursor=db.cursor()
query="SELECT * FROM Students WHERE Name=%s"
name=("Karan",)
cursor.execute(query,name)
for row in myresult:
print(row)위 코드에서 볼 수 있듯이, 쿼리 문자열에 값이 아닌 플레이스홀더 %s를 넣고, 실제 값은 execute() 메서드의 매개변수로 별도 전달합니다. 이렇게 하면 입력값이 쿼리 구조의 일부로 해석되지 않고 순수한 데이터로만 처리되므로, SQL 인젝션 공격을 효과적으로 차단할 수 있습니다.
실행 결과
('Karan', 4, 'Amritsar', 95)마무리: 추가 보안 권장 사항
플레이스홀더를 활용한 매개변수화된 쿼리(prepared statement)는 SQL 인젝션 방어의 핵심입니다. 여기에 더해 다음과 같은 조치를 함께 적용하면 더욱 안전한 웹 애플리케이션을 만들 수 있습니다.
- 입력값 검증: 숫자 필드에는 숫자만 허용하는 등 화이트리스트 방식으로 입력을 검증합니다.
- 최소 권한 원칙: 애플리케이션이 사용하는 DB 계정에 불필요한 권한(DROP, DELETE 등)을 부여하지 않습니다.
- 에러 메시지 최소화: 상세한 DB 에러 메시지를 사용자에게 노출하지 않아 공격자에게 단서를 주지 않습니다.
- ORM 또는 보안 라이브러리 활용: 검증된 프레임워크의 쿼리 빌더나 ORM을 사용하면 실수로 인한 취약점을 줄일 수 있습니다.