security
CHAPTER 81 / 84
읽기 약 2분
FUNCTION
CSRF와 기타 웹 취약점
핵심 개념
⚠️ 방어 관점. CSRF 토큰·SSRF·Path Traversal·파일 업로드 4종 취약점의 Python 감지 + 방어 패턴.
본문
OWASP Top 10 매핑
| 취약점 | OWASP 분류 | 대표 위험 |
|---|---|---|
| CSRF | A01 (Access Control) | 인증된 사용자 사칭 |
| SSRF | A10 (Server-Side Request Forgery) | 내부 네트워크 노출 |
| Path Traversal | A01 (Access Control) | 임의 파일 읽기 |
| 파일 업로드 | A04 (Insecure Design) | RCE (원격 코드 실행) |
CSRF 방어 — 토큰 기반
# ⚠️ 교육 목적, 허가된 환경에서만 사용.
from flask import Flask, session, request, abort
from secrets import token_urlsafe
from functools import wraps
app = Flask(__name__)
app.secret_key = token_urlsafe(32)
def csrf_protect(f):
@wraps(f)
def wrapper(*args, **kwargs):
if request.method == 'POST':
token = request.form.get('csrf_token') or request.headers.get('X-CSRF-Token')
session_token = session.get('csrf_token')
if not token or token != session_token:
abort(403, 'CSRF token mismatch')
if 'csrf_token' not in session:
session['csrf_token'] = token_urlsafe(32)
return f(*args, **kwargs)
return wrapper
@app.route('/transfer', methods=['POST'])
@csrf_protect
def transfer():
amount = request.form['amount']
# 안전: CSRF 토큰 검증 통과
return 'OK'
# ✅ 추가 방어: SameSite=Strict 쿠키
@app.after_request
def set_secure_cookies(response):
response.headers.add(
'Set-Cookie',
f'session={session.sid}; HttpOnly; Secure; SameSite=Strict; Path=/',
)
return responseSSRF 방어 — URL 화이트리스트
import requests
import ipaddress
from urllib.parse import urlparse
PRIVATE_NETWORKS = [
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16'),
ipaddress.ip_network('127.0.0.0/8'),
ipaddress.ip_network('169.254.0.0/16'), # AWS metadata
]
ALLOWED_DOMAINS = {'api.partner.com', 'cdn.example.com'}
def is_safe_url(url: str) -> bool:
parsed = urlparse(url)
# 1. 스키마 검증
if parsed.scheme not in ('http', 'https'):
return False
# 2. 도메인 화이트리스트
if parsed.hostname not in ALLOWED_DOMAINS:
return False
# 3. DNS 해석 후 사설 IP 차단 (DNS rebinding 방어)
import socket
try:
ip_str = socket.gethostbyname(parsed.hostname)
ip = ipaddress.ip_address(ip_str)
for net in PRIVATE_NETWORKS:
if ip in net:
return False
except (socket.gaierror, ValueError):
return False
return True
def fetch_external(url: str) -> bytes:
if not is_safe_url(url):
raise ValueError(f'Unsafe URL: {url}')
return requests.get(url, timeout=5, allow_redirects=False).contentPath Traversal 방어
from pathlib import Path
UPLOAD_DIR = Path('/var/app/uploads').resolve()
def safe_file_read(filename: str) -> bytes:
# ❌ 위험: '../../../etc/passwd' 우회 가능
# path = UPLOAD_DIR / filename
# ✅ 안전: resolve() + 부모 디렉터리 검증
target = (UPLOAD_DIR / filename).resolve()
if UPLOAD_DIR not in target.parents and target != UPLOAD_DIR:
raise ValueError(f'Path traversal attempt: {filename}')
if not target.is_file():
raise FileNotFoundError(filename)
return target.read_bytes()파일 업로드 방어
import magic # python-magic
from pathlib import Path
from secrets import token_hex
ALLOWED_MIME = {'image/jpeg', 'image/png', 'image/webp'}
MAX_SIZE = 5 * 1024 * 1024 # 5MB
UPLOAD_DIR = Path('/var/app/uploads').resolve()
def safe_upload(file_storage) -> str:
# 1. 크기 검증
file_storage.seek(0, 2)
size = file_storage.tell()
file_storage.seek(0)
if size > MAX_SIZE:
raise ValueError('File too large')
# 2. MIME 검증 (magic byte — 확장자 위조 방지)
mime = magic.from_buffer(file_storage.read(2048), mime=True)
file_storage.seek(0)
if mime not in ALLOWED_MIME:
raise ValueError(f'MIME not allowed: {mime}')
# 3. 랜덤 파일명 (원본 이름 사용 금지)
ext = {'image/jpeg': '.jpg', 'image/png': '.png', 'image/webp': '.webp'}[mime]
new_name = f'{token_hex(16)}{ext}'
target = UPLOAD_DIR / new_name
# 4. 실행 권한 차단 (파일 시스템 레벨 — chmod 644)
file_storage.save(target)
target.chmod(0o644)
return new_nameAI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 웹앱 코드에서 CSRF/SSRF/Path Traversal/ 파일 업로드 4종 취약점 가능 위치를 모두 찾아내고 각각 방어 코드를 적용해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
OWASP Top 10 2024 vs 2026 변경 사항과 새롭게 추가된 위협을 한국 SaaS 사례로 비교 분석해서 설명해줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드베이스 전체에서 위 4종 취약점을 자동 스캔하는 통합 점검 스크립트를 만들고 결과를 우선순위별 리포트로 출력해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 SSRF 관련 실제 침해 사례 Top 5 (AWS metadata 노출 등)와 방어 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
CSRF와 기타 웹 취약점은 이 3가지만 확실히 잡으세요
1.4종 취약점 모두 "사용자 제어 데이터 → 신뢰 영역으로 이동" 패턴 — 경계마다 검증·인코딩 적용
2.CSRF + SameSite=Strict 쿠키 + Origin/Referer 검증 3중 방어로 95% 차단
3.다음 챕터에서 argparse CLI — 위 모든 방어 기법을 통합한 자동 점검 도구 제작
공유하기
진행도 81 / 84