반응형
Python으로 MSSQL에 접속할 때, 사용자의 선택이나 조건에 따라 동적으로 SQL 쿼리를 생성해야 하는 상황이 많습니다.
하지만 잘못된 방식으로 쿼리를 구성하면 보안에 치명적인 SQL Injection 문제가 발생할 수 있죠.
이번 포스팅에서는 아래 내용을 쉽게 정리해보겠습니다.
f-string
을 이용한 동적 쿼리 생성법- SQL Injection 방지법 (✅
params
사용) - 실전 예제와 비교
📌 1. 기본 구조: MSSQL 접속과 쿼리 실행
import pyodbc
conn = pyodbc.connect(
'DRIVER={ODBC Driver 17 for SQL Server};SERVER=서버주소;DATABASE=DB명;UID=아이디;PWD=비번'
)
cursor = conn.cursor()
💥 2. 잘못된 방법: f-string으로 직접 값을 넣는 경우
# ❌ SQL Injection 위험!
table = 'users'
status = 'active'
query = f"SELECT * FROM {table} WHERE status = '{status}'"
cursor.execute(query)
이런 방식은 입력값이 조작될 경우, 다음과 같은 공격이 가능합니다:
status = "'; DROP TABLE users; --"
실행 시:
SELECT * FROM users WHERE status = ''; DROP TABLE users; --'
🚨 실제 테이블이 삭제될 수도 있습니다.
✅ 3. 안전한 방법: 파라미터 바인딩 (?
또는 params
)
table = 'users'
status = 'active'
# 테이블 이름은 f-string (주의 필요), 값은 parameter 바인딩
query = f"SELECT * FROM {table} WHERE status = ?"
cursor.execute(query, (status,))
?
위치에 안전하게 값이 바인딩되므로, SQL Injection 공격을 방지할 수 있습니다.
⚠️ 테이블명, 컬럼명은 바인딩할 수 없으므로 f-string 사용 시 꼭 화이트리스트 검증 필요!
🧠 4. 테이블 이름도 유동적인 경우 → 화이트리스트 사용
allowed_tables = ['users', 'orders', 'products']
input_table = 'users'
if input_table not in allowed_tables:
raise ValueError("허용되지 않은 테이블명입니다.")
query = f"SELECT * FROM {input_table} WHERE status = ?"
cursor.execute(query, (status,))
✅ 이렇게 하면 f-string을 써도 안전하게 테이블명을 동적으로 넣을 수 있습니다.
🛠 5. 실전 예제: 날짜 필터 + 상태 필터 동적 조합
filters = []
params = []
# 날짜 조건
start_date = '2024-01-01'
end_date = '2024-12-31'
filters.append("created_at BETWEEN ? AND ?")
params += [start_date, end_date]
# 상태 조건
status = 'active'
if status:
filters.append("status = ?")
params.append(status)
where_clause = " AND ".join(filters)
query = f"SELECT * FROM users WHERE {where_clause}"
cursor.execute(query, params)
📌 동적 조건 조합 + 파라미터 바인딩 = 실무에서 가장 자주 사용하는 패턴!
🎯 마무리 요약
항목 | 설명 |
---|---|
f-string | 쿼리 구성은 편리하지만 값 직접 넣지 말 것 |
? 파라미터 |
SQL Injection 방지용 필수 |
테이블/컬럼명 | 반드시 화이트리스트 검증 |
복수 조건 조합 | 리스트로 조건 쌓고 join() 으로 조합 |
✅ 쿼리를 동적으로 구성할 땐 항상 보안과 가독성을 동시에 고려해야 합니다.
🏷 태그
#Python #MSSQL #SQLInjection #파라미터바인딩 #쿼리자동화 #동적SQL #pyodbc
반응형
'Programming' 카테고리의 다른 글
📡 Python으로 MSSQL 저장 프로시저 실행하기 (파라미터 전달까지 완벽 정리!) (0) | 2025.03.28 |
---|---|
📬 Python으로 텔레그램에 알림 보내는 방법 (봇 API 활용) (1) | 2025.03.27 |
📦Python 가상환경(venv) 사용법 + `requirements.txt` 완전정복 (0) | 2025.03.25 |
🔁 MSSQL에서 반복문 처리하기: WHILE vs CURSOR 기초 정리 (0) | 2025.03.24 |
🗂 Python으로 CSV → MSSQL 대량 업로드 (속도 비교 포함) (0) | 2025.03.24 |