취약점 유형❗ 네트워크 평문 통신 (MITM)
설명: HTTPS 대신 HTTP 또는 SSL 미설정 시, 중간자 공격에 노출
방어전략:
✅ 모든 API 요청은 HTTPS 사용
✅ SSL 핀닝 적용 (react-native-ssl-pinning)
✅ 인증서 유효성 검증 (서명, CN 확인 등)
취약점 유형❗ 민감 정보 평문 저장
설명: 토큰, 비밀번호, 사용자 정보가 암호화 없이 저장될 경우 노출 위험
방어전략:
✅ react-native-encrypted-storage, SecureStore, Keychain 사용
✅ AsyncStorage에는 민감 정보 절대 저장 금지
✅ 저장 시 AES 기반 암호화 적용
취약점 유형❗ 디버그 코드 유출
설명: __DEV__, console.log, debugger 코드가 빌드에 포함되면 정보 유출
방어전략:
✅ 릴리즈 빌드 시 console, debugger 제거
✅ babel-plugin-transform-remove-console 사용
✅ BuildConfig.DEBUG 체크로 실행 조건 분리
취약점 유형❗ JS 번들 역공학
설명: apk 또는 ipa 안의 JS 코드를 추출하여 분석/공격 가능
방어전략:
✅ Hermes 엔진 사용 (bytecode로 난독화)
✅ ProGuard 활성화 (Android)
✅ 핵심 로직은 네이티브 코드로 이관
취약점 유형❗ 루팅/탈옥 환경 허용
설명: 루팅된 기기에서 앱 실행 시, 시스템 API 악용 가능
방어전략:
✅ react-native-root-detect, react-native-jailbreak-detect 사용
✅ 감지 시 앱 종료 또는 제한
✅ Emulator 감지 옵션도 함께 적용
취약점 유형❗ WebView XSS
설명: WebView에 악성 JS 삽입 시, 쿠키/세션 등 탈취 가능
방어전략:
✅ 외부 URL 로드 금지 (originWhitelist)
✅ injectedJavaScript, onMessage 제한
✅ DOMPurify 등 클라이언트 측 sanitize 적용 (내장 페이지 사용 시)
취약점 유형❗ 토큰 탈취
설명: Refresh Token/Access Token이 외부에 노출되면 세션 탈취
방어전략:
✅ Keychain, SecureStore 등 안전한 저장소 사용
✅ 토큰은 최대한 짧은 유효시간 사용 + Refresh로 갱신
✅ 로그아웃 시 토큰 삭제 + 서버에서도 만료 처리
취약점 유형❗ 권한 과다 요청
설명: 사용하지 않는 카메라, 위치, 연락처 등 권한을 앱이 요청할 경우
방어전략:
✅ 최소 권한만 요청
✅ react-native-permissions로 세분화 관리
✅ AndroidManifest.xml / Info.plist 점검
보안 좋은 습관
민감 데이터는 반드시 암호화된 저장소에 저장
HTTPS는 기본, SSL 핀ning은 가능하면 적용
루팅/디버깅/에뮬레이터 탐지 라이브러리 도입
WebView 사용 시 반드시 sanitize 처리
API 통신은 JWT + 갱신 로직 + 타임아웃 설정
Release 빌드 시 로그/디버그 코드 제거
위험한 설정 vs 안전한 설정
❌ 위험한 설정
await AsyncStorage.setItem("accessToken", token);
✅ 안전한 설정
import EncryptedStorage from 'react-native-encrypted-storage';
await EncryptedStorage.setItem("accessToken", token);
보안 마인드셋
“모바일 기기는 언제든 분실되거나 탈취될 수 있다.
따라서 모든 로컬 데이터, 통신, 실행 환경은 위험을 전제로 보호하라.”
Spring Boot + React Native 통합 보안 구조
1. 인증 / 인가 구조 (Authentication & Authorization)
로그인 방식 | JWT 기반 인증 | Spring Security + JWT |
토큰 저장 | RN 클라이언트에서 AccessToken, RefreshToken 보관 | EncryptedStorage, SecureStore |
토큰 갱신 | AccessToken 만료 시 RefreshToken으로 재발급 | /auth/refresh API 사용 |
로그아웃 | 클라이언트 토큰 삭제 + 서버 RefreshToken 블랙리스트화 | Redis or DB 사용 |
JWT 인증 흐름
[React Native] → 로그인 요청 → [Spring Boot]
→ AccessToken + RefreshToken 응답
→ 모든 요청에 Authorization: Bearer {AccessToken}
→ 토큰 만료 → /auth/refresh 호출 → 새 토큰 발급
2. 클라이언트-서버 통신 보안
프로토콜 | ✅ HTTPS 필수 (https://api.example.com) |
SSL 핀닝 | react-native-ssl-pinning으로 서버 인증서 바인딩 |
인증 헤더 | axios 인터셉터에 Authorization: Bearer {token} 자동 삽입 |
응답 검증 | JWT 서명 검증, 만료 여부 검사 (401 → 재로그인) |
3. 민감 정보 저장소
AccessToken | EncryptedStorage |
RefreshToken | EncryptedStorage (되도록 서버만 저장 권장) |
사용자 프로필 | EncryptedStorage or 암호화된 SQLite |
앱 설정값 | SecureStore or AsyncStorage (비민감한 것만) |
❗ 절대 AccessToken을 AsyncStorage에 저장하지 말 것
4. 입력값 검증 및 XSS 방어
React Native | 입력값 유효성 검사 (길이, 포맷 등) |
WebView | DOMPurify, originWhitelist, allowFileAccessFromFileURLs=false |
Spring Boot | XSS 필터 전역 적용 (RequestWrapper + escapeHtml4) |
HTML 출력 시 | dangerouslySetInnerHTML → 반드시 sanitize 적용 |
5. SQL Injection / 권한 제어
SQL Injection | JPA/QueryDSL/PreparedStatement로 바인딩 처리 |
사용자 인증정보 접근 | 로그인한 사용자의 ID로 DB 쿼리 제한 |
관리자 API 분리 | /admin/** 경로 + @PreAuthorize("hasRole('ADMIN')") |
6. 로그 / 감사 / 추적항목 설명
요청 로그 | 모든 요청/응답 로그는 Logback 또는 AOP로 남기기 |
사용자 액션 로그 | DB 또는 로그파일로 남겨 추적성 확보 |
예외 로그 | Spring에서 @ControllerAdvice로 글로벌 핸들링 |
7. 토큰 만료 + 보안 패턴
AccessToken 만료 | 401 응답 시 → RefreshToken으로 재발급 |
RefreshToken 만료 | 자동 로그아웃 처리 |
로그인 중복 | RefreshToken을 DB에서 1개만 유지 |
로그아웃 처리 | RefreshToken 삭제 + Redis 블랙리스트 등록 |
8. 배포 전 체크리스트
- HTTPS 적용 완료 (Spring + nginx, 인증서 설치)
- React Native 앱에 SSL 핀닝 적용
- 모든 민감정보는 EncryptedStorage에 저장
- WebView는 XSS 방어 필터 적용
- AccessToken 유효성 검증 및 자동 재발급 적용
- Spring Boot 전역 XSS 필터, 에러 핸들러 설정
- .env, application-secret.yml은 Git에 절대 포함 X
보안 마인드셋
"모바일은 유출되고, 서버는 공격받고, 통신은 감시당한다.
모든 구간에서 누군가 지켜보고 있다고 가정하고 설계하라."
'Computer > Computer Security' 카테고리의 다른 글
웹 보안 및 모바일 보안 (0) | 2025.04.01 |
---|---|
이메일 보안 (0) | 2025.04.01 |
DB(데이터베이스) 환경 보안 체크리스트 (0) | 2025.04.01 |
보안 시스템 II (1) | 2025.04.01 |
보안 시스템 I (0) | 2025.04.01 |