Files
BASE_REACT_PROJECT/SECURE_RULE.md
2026-01-30 11:39:54 +09:00

253 lines
11 KiB
Markdown

# Secure Coding Master Document (정돈본, 중복 제거)
**대상 스택:** Spring Boot (Session + Spring Security) + MyBatis + MariaDB / React + Vite + Axios + React Context
**목표:** OWASP Top 10 기반 주요 취약점 방지 + CodeMind/SolidStep 등 정적 분석 경고(특히 High/Critical) 80% 이상 사전 감소
**주의:** 이 문서는 “요약”이 아니라 “정돈(배치 조정)” 문서이며, 중복되는 설명만 1회만 등장하도록 재배치함.
---
## 0. 서문 (초기 리서치 원문 포함)
안전한 소프트웨어 개발을 위해 코드 구현 단계에서 보안 약점을 제거하고 예방하는 시큐어 코딩 규칙을 정리했습니다. 아래 규칙들을 따르면 OWASP Top 10을 비롯한 주요 취약점을 효과적으로 방지할 수 있으며, CodeMind나 SolidStep 같은 정적 분석 도구에서도 발견되는 보안 결함의 80% 이상을 사전에 줄일 수 있을 것입니다. 각 규칙에는 간략한 설명과 예시가 포함되어 있으므로 개발 시 참고하시기 바랍니다.
---
## 1. 입력 데이터 검증 및 표현 (초기 리서치 원문 + 스택 적용)
외부로부터 입력받은 데이터는 반드시 유효성을 검증하고 적절히 필터링/변환해야 합니다. 입력값 검증이 부족하면 SQL 삽입, XSS 등의 치명적인 공격으로 이어질 수 있습니다.
### 1.1 SQL 삽입(SQL Injection)
- **원칙:** 사용자 입력이 SQL 쿼리에 직접 포함되지 않도록 한다.
- **적용:** Prepared Statement 또는 MyBatis `#{}` 바인딩 사용.
- **예시:**
- `"SELECT * FROM users WHERE id = ?"` 형태로 쿼리 작성
- `pstmt.setString(1, userInput)` 방식으로 바인딩
- 입력은 데이터로만 취급되어 쿼리 구조 변경 불가
- **MyBatis 추가 규칙:** `${}` 전면 금지(문자열 치환) / `#{}`만 사용(바인딩)
### 1.2 운영체제 명령어 삽입(Command Injection)
- **원칙:** `system()`, `exec()` 호출 시 사용자 입력이 들어가지 않도록 한다.
- **적용:** 허용된 명령 **Whitelist** 기반 실행 + 특수문자 필터링
- **차단 특수문자 예:** `|`, `;`, `&`, `>`, `<`, `` ` ``
- **위험 예:** `os.system(userInput)`
- **권장:** “허용된_프로그램목록”에 존재하는 명령만 실행
### 1.3 크로스사이트 스크립팅(XSS)
- **원칙:** 출력에 사용자 입력값이 포함될 경우 HTML 엔티티 인코딩(escape) 적용
- **예시:** `<`, `>``&lt;`, `&gt;`
- **라이브러리 예:**
- Java: `StringEscapeUtils.escapeHtml4()`
- Python: `html.escape()`
- **템플릿 엔진:** 기본 자동 escape 제공(Django/Jinja2 등) → 적극 활용
### 1.4 경로 조작(Path Traversal)
- **원칙:** 파일 경로나 자원 식별자에 외부 입력값 사용 시 “허용된 경로/이름”만 통과
- **차단 포인트:** `../` 등 상위 디렉토리 접근
- **예시:** 업로드 파일명에서 `"/"`, `"\"`, `".."` 제거 또는 포함 시 거부
- **추가:** 파일 열기 전 확장자 제한(.txt, .csv 등) + 존재 여부 확인
### 1.5 위험한 파일 업로드
- **원칙:** **화이트리스트 방식**으로 확장자 + MIME 제한
- **예시:** 이미지 업로드 시 `.jpg`, `.png`만 허용 / 실행 파일(PHP/EXE 등) 차단
- **추가:** 파일 크기/개수 제한, 업로드 디렉토리 최소 권한(실행 권한 제거)
- **저장 권장:** 웹루트 밖 저장 + 저장 파일명 변환(해시/UUID)
### 1.6 신뢰되지 않은 URL 리다이렉트(Open Redirect)
- **원칙:** 사용자 입력을 그대로 redirect 대상에 사용 금지
- **대응:** 미리 정의된 도메인/경로 allowlist만 허용
- **예시:** `nextURL``response.sendRedirect()`에 직접 사용 금지
### 1.7 HTTP 응답 분할(Response Splitting)
- **원칙:** 사용자 입력이 HTTP 헤더로 들어갈 때 `\r\n` 제거/차단
- **대응:** 프레임워크의 안전한 헤더/쿠키 설정 API 사용(직접 Set-Cookie 조작 금지)
### 1.8 정수 오버플로우/언더플로우
- **원칙:** 숫자형 입력은 범위 검사 필수(음수/과대값 차단)
- **예시:** 배열 크기 입력 시 매우 큰 값 거부, 덧셈/곱셈 overflow 가능성 검사
### 1.9 보안 메커니즘 우회 방지
- **원칙:** 클라이언트 파라미터/쿠키를 신뢰하여 인증/인가 판단 금지
- **예시:** `isAdmin=true` 같은 hidden 필드/파라미터로 권한 판단 금지
- **대응:** 서버 세션/DB 기반으로 권한 확인 + 가격/수량은 서버 재계산/검증
---
## 2. 보안 기능(인증/인가/권한) (초기 리서치 원문 + 스택 적용)
### 2.1 중요 기능에 대한 인증 요구
- 인증 없이 민감 기능 허용 금지(관리자 페이지/개인정보 열람/금융 등)
- 모든 민감 URL에 인증 체크(필터/인터셉터/보안 설정)
### 2.2 철저한 접근제어(인가)
- 요청마다 “현재 사용자가 접근 권한이 있는가?”를 서버에서 확인
- 클라이언트 메뉴 숨김은 신뢰 불가
- RBAC 적용 + 기본 정책은 **Deny-by-default**
- 예: 삭제 기능 호출 시 세션 userId와 소유자 비교 후 처리
### 2.3 세션 관리 보안
- 쿠키에 `HttpOnly`, `Secure` 설정
- 로그인 성공 시 세션 재발급(Session Fixation 방지)
- 로그아웃 시 세션 무효화
- 세션 타임아웃 설정
- 다중 로그인 시 세션 분리 관리(정보 섞임 방지)
### 2.4 최소 권한(Least Privilege)
- DB는 root/admin 사용 금지, 최소 권한 계정 사용
- 파일/설정/업로드 폴더 권한 최소화
- 애플리케이션 프로세스도 불필요한 관리자 권한 금지
### 2.5 안전한 암호화 알고리즘 사용
- 비밀번호: BCrypt/PBKDF2/Scrypt 등 “느린 해시” 사용
- DES/MD5/SHA-1 사용 금지
- 전송: TLS(HTTPS) 강제
### 2.6 민감정보 저장 및 관리
- 비밀번호/API키/토큰 평문 저장/하드코딩 금지
- 환경변수/Vault/Secret Manager 활용
- 기본 비밀번호 반드시 변경
- 설정 파일 접근 권한 통제, 필요 시 암호화/난독화 고려
### 2.7 암호 키 관리
- 마스터키/개인키: HSM/KeyVault 보관 권장
- 키 분리, 정기 교체, 장기 동일 키 사용 금지
- 메모리 상 키 취급 최소화(가능하면 즉시 제거)
---
## 3. 시간 및 상태(동시성/상태관리)
### 3.1 Race Condition / TOCTOU
- 검사 시점과 사용 시점이 달라 생기는 취약점 주의
- 원자적 처리, 파일 잠금(lock), 안전한 임시파일 생성 API(mkstemp 등)
### 3.2 무한 루프/재귀 제어
- 종료 조건 명확화, 반복 상한 설정
- 입력 기반 폭증 방지(DoS 대응)
### 3.3 일관된 상태 유지
- 트랜잭션/락으로 일관성 보장
- 불변객체(Immutable) 활용 고려
- thread-safe하지 않은 객체는 동기화 또는 안전한 대체 사용
### 3.4 자원 고갈 방지
- 스케줄러 주기, 스레드풀 크기, 큐 정책 과도 설정 금지
- Rate Limiting, 백오프, 드롭 정책 등으로 보호
---
## 4. 에러 처리(예외/상태코드/페이지)
### 4.1 오류 메시지 정보 노출 금지
- 스택트레이스/경로/쿼리/내부정보 노출 금지
- 사용자 메시지는 일반화, 상세는 로그에만
### 4.2 예외 상황 대응
- 모든 예외를 처리(예외 삼키지 않기)
- catch 블록 비우기 금지
### 4.3 계단식 예외 처리
- 구체 예외 → 포괄 예외 순으로 처리
- 글로벌 예외 핸들러로 누락 방지
### 4.4 HTTP 상태코드/에러 페이지 관리
- 401/403/404/500 등 의미에 맞게 반환
- 사용자용 에러 페이지 제공(서버 정보 노출 금지)
### 4.5 오류 로깅/모니터링
- 누가/언제/무엇을 했는지 기록(민감정보 제외)
- 반복 공격 징후 감지 후 차단/보완
---
## 5. 코드 오류(코딩 품질 기반 보안)
- Null 체크, Optional 활용
- 자원 해제(try-with-resources / with)로 누수 방지
- (C/C++) 버퍼 오버플로우 방지(안전한 함수 사용, 경계 체크)
- 산술 오류/오버플로우, 타입 변환 체크
- 함수 반환값/오류코드 확인
- deprecated/취약 API 사용 금지(e.g., eval/exec, Math.random 보안용 사용 금지)
---
## 6. 캡슐화(Encapsulation)
- 디버그/테스트/백도어 코드 제거
- 내부 정보 노출 방지(에러/헤더/HTML 소스)
- private 데이터는 복사본 반환, 읽기전용 뷰 제공
- 세션/전역 변수에 사용자별 데이터 저장 금지
- 민감정보 최소 노출(마스킹/필요 최소 필드만)
---
## 7. API 오용 방지
- DNS 기반 보안 판단 지양(스푸핑 가능)
- SSL 검증 우회 금지
- 보안용 난수는 SecureRandom/secrets 사용
- 외부 라이브러리 취약점 정기 점검(Dependabot/Snyk 등)
- 보안 기능은 직접 구현 지양(검증된 라이브러리 우선)
---
## 8. 스택 적용: 공통 금지 리스트(응답/로그/저장)
### 8.1 API 응답에 절대 포함 금지
- password(평문/해시), salt
- sessionId/JSESSIONID, accessToken/refreshToken/OAuth token
- Authorization/Cookie 전체
- 주민번호/카드번호/CVV/계좌/OTP
- 내부 IP/서버 경로/DB 정보/SQL 원문
- StackTrace/클래스명/라인번호/환경변수 원문/디버그 플래그
### 8.2 로그에 절대 기록 금지
- password/token/sessionId
- Authorization/Cookie 전체
- 요청/응답 raw dump
- 개인정보 전체(필요 시 마스킹 후 일부)
---
## 9. BACKEND 적용 규칙(요약)
- DTO + @Valid, 화이트리스트 검증, 길이/범위 제한
- MyBatis `#{}`만 사용, `${}` 금지, ORDER BY enum 매핑
- Command Injection 방지: allowlist + 특수문자 차단, 문자열 결합 금지
- Path Traversal 방지: normalize + BASE_DIR 하위 검증
- 파일 업로드 7종 세트(확장자/MIME/시그니처/UUID/웹루트밖/제한/위험타입차단)
- 세션 쿠키 보안옵션(HttpOnly/Secure/SameSite), 세션 재발급, 최소 세션 사용자 모델
- 인가/IDOR: 소유권 검증, deny-by-default
- 예외 계단식 + 표준 ErrorResponse + traceId
- 로그 민감정보 금지 + 감사 로그 분리
- try-with-resources, 타임아웃, 트랜잭션 최소화, TOCTOU/RateLimit 고려
- CORS Origin allowlist, credentials + "*" 금지, CSRF 정책 명시
---
## 10. FRONTEND 적용 규칙(요약)
- AuthContext 단일화, 페이지별 /me 중복 호출 금지
- Axios 단일 인스턴스 + 인터셉터(401/403/404/500 처리), 401 루프 방지
- XSS: dangerouslySetInnerHTML/innerHTML 금지, 필요 시 DOMPurify sanitize + allowlist
- URL 인코딩(encodeURIComponent), javascript: 스킴 차단, eval/new Function 금지
- localStorage/sessionStorage에 인증정보 저장 금지, env에 비밀키 금지
- useEffect cleanup, timer clear, WebSocket close, revokeObjectURL
---
## 11. CI/자동 점검(요약)
### 11.1 Backend Fail 권장
- MyBatis `${}` 사용
- 문자열 SQL 조합
- 사용자 입력 기반 파일 경로 조합
- printStackTrace / empty catch
- 민감정보 응답/로그 노출
- CORS wildcard + credentials
- CSRF disable(보완책 없음)
- 약한 암호(MD5/SHA1/Math.random)
### 11.2 Frontend Fail 권장
- dangerouslySetInnerHTML / innerHTML
- eval/new Function
- localStorage token/user/role 저장
- 운영 빌드 console.log
- npm audit High 이상
### 11.3 공통
- dependency vulnerability scan
- secrets scan
- release gate(HTTPS/쿠키/에러노출/업로드경로/관리자 인가)
---
# END