시큐어 코딩(Secure Coding)은 보안 취약점을 유발하는 코딩 실수를 방지하기 위해 보안을 고려해 소프트웨어를 작성하는 방법론이다. OWASP Top 10이 가장 널리 알려진 취약점 분류다.
OWASP Top 10 (2021)
| 순위 | 취약점 | 예시 |
|---|
| A01 | 접근 제어 실패 | IDOR, 권한 없는 API 접근 |
| A02 | 암호화 실패 | 평문 비밀번호, 약한 암호화 |
| A03 | 인젝션 | SQL 인젝션, XSS |
| A04 | 불안전한 설계 | 비즈니스 로직 결함 |
| A05 | 보안 설정 오류 | 기본 계정, 불필요한 서비스 |
| A06 | 취약한 컴포넌트 | Log4Shell, 구 버전 라이브러리 |
| A07 | 인증 및 식별 실패 | 약한 세션 관리, 무제한 로그인 |
| A08 | 소프트웨어/데이터 무결성 | CI/CD 파이프라인 검증 부재 |
| A09 | 로깅 및 모니터링 실패 | 보안 이벤트 미기록 |
| A10 | SSRF | 내부 서비스 요청 위조 |
SQL 인젝션 방어
python
# 취약한 코드
def bad_login(username, password):
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
# username = "admin' --" 입력 시 인증 우회!
# 안전한 코드 (파라미터화된 쿼리)
def safe_login(username, password):
query = "SELECT * FROM users WHERE username=? AND password=?"
cursor.execute(query, (username, password))
# 사용자 입력이 SQL 문법으로 해석되지 않음
# ORM 사용
def orm_login(username, password):
user = User.query.filter_by(username=username).first()
return user and user.check_password(password)
XSS 방어
javascript
// 취약한 코드
element.innerHTML = userInput; // XSS 가능!
// 안전한 코드
element.textContent = userInput; // HTML 이스케이프 자동 처리
// React는 기본적으로 XSS 방어
const SafeComponent = ({ userInput }) => (
<div>{userInput}</div> // 자동 이스케이프
);
// DOMPurify로 HTML 정화 (리치 텍스트 허용 시)
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
입력 검증 원칙
python
import re
from functools import wraps
def validate_input(schema):
"""입력 검증 데코레이터"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for field, rules in schema.items():
value = kwargs.get(field)
if rules.get('required') and not value:
raise ValueError(f"{field} is required")
if value and 'pattern' in rules:
if not re.match(rules['pattern'], value):
raise ValueError(f"Invalid {field} format")
if value and 'max_length' in rules:
if len(value) > rules['max_length']:
raise ValueError(f"{field} too long")
return func(*args, **kwargs)
return wrapper
return decorator
@validate_input({'username': {'required': True, 'pattern': r'^[a-zA-Z0-9_]{3,20}$'}})
def create_user(username, email):
pass
관련 문서