🛡️ Flask (CRUD API Only) XSS 방지 대책
API 서버에서 가장 중요한 XSS 방지책은 클라이언트 측에서 예상치 못한 방법으로 스크립트가 실행되는 것을 막는 것입니다.
1. 📝 입력 데이터 정제 (Input Sanitization)
Flask가 사용자로부터 받은 데이터를 데이터베이스에 저장하기 전, 또는 응답으로 보내기 전에 잠재적인 악성 HTML/스크립트 코드를 제거하는 과정입니다.
✅ 샘플 코드: bleach 라이브러리 사용
파이썬에서는 bleach와 같은 라이브러리를 사용하여 사용자 입력에서 HTML 태그와 속성을 안전하게 제거할 수 있습니다.
Bash
# 💡 라이브러리 설치
pip install bleach
Python
import bleach
from flask import Flask, request, jsonify
app = Flask(__name__)
# 허용할 HTML 태그 및 속성 목록 (API 서버이므로 모두 비워두는 것이 가장 안전)
ALLOWED_TAGS = []
ALLOWED_ATTRIBUTES = {}
@app.route('/api/posts', methods=['POST'])
def create_post():
data = request.get_json()
# ❌ 정제 없이 직접 사용 (위험!)
# title = data.get('title')
# ✅ bleach를 사용하여 모든 HTML 태그를 제거하고 안전한 텍스트로 만듦
raw_title = data.get('title', '')
sanitized_title = bleach.clean(
raw_title,
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES
)
# DB 저장 로직: sanitized_title을 저장
# ...
return jsonify({
"message": "Post created successfully",
"title": sanitized_title
}), 201
if __name__ == '__main__':
app.run(debug=True)
설명: API 서버의 목적은 순수한 데이터 전송이므로, tags=[]로 설정하여 모든 HTML을 제거하고 순수한 텍스트만 남기도록 강제하는 것이 가장 안전합니다.
2. 🛡️ 보안 헤더 설정 (Security Headers)
API 응답에 보안 관련 HTTP 헤더를 추가하여, 설령 XSS 공격 코드가 삽입되더라도 브라우저가 이를 실행하는 것을 억제하도록 지시합니다.
✅ 샘플 코드: Content-Security-Policy 및 기타 헤더
after_request 훅을 사용하여 모든 API 응답에 자동으로 보안 헤더를 추가합니다.
Python
from flask import Flask, jsonify
app = Flask(__name__)
# ... (API 엔드포인트 코드) ...
@app.after_request
def add_security_headers(response):
# 1. Content Security Policy (CSP) 설정
# default-src 'self' : 모든 리소스(스크립트, 스타일 등)를 현재 도메인에서만 로드하도록 제한
# object-src 'none' : <object>, <embed>, <applet> 태그 사용 금지
response.headers['Content-Security-Policy'] = "default-src 'self'; object-src 'none';"
# 2. X-Content-Type-Options: MIME 스니핑(Sniffing) 방지
response.headers['X-Content-Type-Options'] = 'nosniff'
# 3. X-Frame-Options: Clickjacking 방지 (API는 필요 없으나 일반 웹에선 중요)
response.headers['X-Frame-Options'] = 'DENY'
# 4. X-XSS-Protection (대부분의 모던 브라우저에서는 CSP로 대체됨)
# response.headers['X-XSS-Protection'] = '0' # CSP 사용 시 비활성화 권장
return response
# 예시 GET 엔드포인트
@app.route('/api/status', methods=['GET'])
def get_status():
return jsonify({"status": "OK", "message": "Security headers applied."})
if __name__ == '__main.어요':
app.run(debug=True)
설명:
- CSP (Content-Security-Policy): 가장 강력한 방어 기제 중 하나입니다. default-src 'self'는 악성 스크립트가 외부 출처에서 로드되는 것을 차단합니다.
- X-Content-Type-Options: nosniff: 브라우저가 응답의 MIME 타입을 추측하는 것을 막아, 서버가 text/plain이라고 보낸 응답을 브라우저가 강제로 text/html로 해석하여 실행하는 것을 방지합니다.
3. 🍪 HttpOnly 쿠키 사용
세션 관리나 인증에 쿠키를 사용할 경우, XSS 공격자가 사용자의 세션 토큰을 훔쳐가는 것을 막기 위해 이 설정을 반드시 적용해야 합니다.
✅ 샘플 코드: 쿠키 설정 시 httponly=True 옵션 사용
Python
from flask import make_response, jsonify
@app.route('/api/login', methods=['POST'])
def login():
# ... 인증 로직 ...
response = make_response(jsonify({"message": "Login successful"}))
# ✅ HttpOnly 설정: 클라이언트 측 JavaScript에서 쿠키 접근 불가능
# (XSS를 통한 세션 하이재킹 방지)
response.set_cookie(
'session_token',
'secure_random_token_value',
httponly=True,
secure=True, # HTTPS 환경에서만 전송
samesite='Lax' # CSRF 방지에도 도움
)
return response
이 세 가지 방법을 통해 Flask API 서버는 사용자 입력 처리, 응답 헤더 설정, 세션 관리에 있어 강력한 XSS 방어 환경을 구축할 수 있습니다.
'Web Security' 카테고리의 다른 글
| CSRF(일부XSS포함) 방지책 (ReactJS + Flask) (0) | 2025.12.02 |
|---|---|
| XSS 방지책 (Express.js) (0) | 2025.12.02 |
| XSS 방지책 (ReactJS) (0) | 2025.12.02 |
| CSRF (Cross-Site Request Forgery) attack (0) | 2025.12.02 |
| 크로스 사이트 스크립팅 (Cross-Site Scripting, XSS) (0) | 2025.11.30 |