개념
모바일 앱의 신뢰 경계는 어디에 있나
서버 애플리케이션을 검증할 때 우리는 "서버는 우리 것"이라는 가정 위에 서 있다. 모바일 앱에는 그 가정이 없다. 배포된 바이너리는 공격자가 완전히 통제하는 기기 안에서 돌아간다. 디스어셈블할 수 있고, 저장소를 열어볼 수 있고, 프로세스에 후킹할 수 있고, 시스템 시간을 바꿀 수 있다. 모바일 보안 검증의 첫 번째 원칙은 이렇게 정리된다.
클라이언트에서 수행되는 검사는 시간을 벌어주는 장치 일 뿐이고, 권한·금액·자격에 대한 판정은 서버에서만 유효하다.
그래서 점검은 두 갈래다. 서버가 제대로 판정하는지(레슨 2·3이 그대로 적용된다), 그리고 기기에 남는 것과 플랫폼 표면에서 새는 것. 이 레슨은 두 번째를 다룬다.
MASVS와 MASTG — 기준과 방법의 분리
OWASP의 모바일 애플리케이션 보안 프로젝트(OWASP MAS)는 문서를 역할별로 쪼개 놓았다.
| 문서 | 역할 | 형태 |
|---|---|---|
| MASVS (Mobile Application Security Verification Standard) | 무엇을 만족해야 하는가 — 보안 요구사항 | MASVS-STORAGE-1 같은 제어 항목 |
| MASWE (Mobile Application Security Weaknesses) | 요구사항이 깨질 때 나타나는 약점 목록 | MASWE-nnnn |
| MASTG (Mobile Application Security Testing Guide) | 어떻게 확인하는가 — 테스트 절차·기법·지식 문서 | MASTG-TEST, MASTG-TECH, MASTG-KNOW, MASTG-BEST, MASTG-DEMO |
MASVS의 현재 판은 v2.1.0(2024-01-18 릴리스) 이다. 큰 변화는 v2.0.0(2023-04)이었고, 항목이 대폭 정리되면서 문서의 성격이 "체크리스트"에서 "추상 제어 집합"으로 바뀌었다.
v2.1.0에서 프라이버시 그룹이 추가됐다. 사내 문서가 MASVS-V2.1 같은 V-번호 형식 을 쓰면 그건 v1.x 번호이므로 현행 그룹 이름으로 다시 매핑해야 한다.
8개 제어 그룹
MASVS v2.x는 제어를 여덟 개 그룹으로 묶는다.
| 그룹 | 다루는 것 |
|---|---|
| MASVS-STORAGE | 기기에 저장되는 민감 데이터의 보호 |
| MASVS-CRYPTO | 암호 기능의 구현 — 알고리즘·키 관리 |
| MASVS-AUTH | 인증·인가 메커니즘 |
| MASVS-NETWORK | 네트워크 통신의 보호 |
| MASVS-PLATFORM | 플랫폼과의 상호작용 — IPC, WebView, UI 노출 |
| MASVS-CODE | 코드 품질과 의존성 — 업데이트·서드파티 |
| MASVS-RESILIENCE | 역공학·변조에 대한 저항 |
| MASVS-PRIVACY | 사용자 프라이버시 — 데이터 최소화, 투명성, 이용자 통제 |
여덟 개 중 RESILIENCE 하나만 "심층 방어" 성격 이라는 점이 중요하다. 나머지가 깨지면 결함이지만, RESILIENCE가 약한 것은 그 자체로는 결함이 아닐 수도 있다. 뒤에서 다시 다룬다.
검증 프로파일 — 어디까지 요구할 것인가
v1.x의 MASVS는 문서 안에 L1·L2·R 세 개의 검증 레벨을 갖고 있었다. v2.0.0에서 이 레벨을 MASVS 본문에서 떼어내 MASTG 쪽으로 옮겼다. 같은 제어라도 요구 수준에 따라 확인할 테스트가
달라지기 때문이다 — MASVS-STORAGE-1에 대해 "앱 내부 저장소에 평문으로 두는 것이 허용되는가"의 답은 프로파일에 따라 갈린다.
현재는 MASTG가 MAS 테스트 프로파일(MAS-L1 / MAS-L2 / MAS-R) 을 정의하고, 그 프로파일이 어떤 제어와 테스트가 범위에 들어오는지를 결정한다. 프로파일별 제어 매핑의 정본은 MASTG 원문에서 확인한다 — 문서가 개편 중이라 사내 체크리스트에 박아두면 금방 낡는다.
실무에서 프로파일을 고르는 기준은 이렇게 잡으면 된다.
| 앱의 성격 | 권장 출발점 |
|---|---|
| 콘텐츠 조회, 로그인 없음, 민감 데이터 없음 | MAS-L1 — 표준 보안 위생 수준 |
| 로그인이 있고 개인정보·결제 정보를 다룬다 | MAS-L2 — 금융·의료·커머스 대부분 |
| 앱 내부 로직 자체가 보호 대상(콘텐츠 DRM, 게임 치팅, 오프라인 라이선스) | MAS-L2 + MAS-R |
프로파일은 QA가 혼자 정하지 않는다. 보안 담당·프로덕트·법무가 합의한 문서 로 남기고 그것을 근거로 테스트 범위를 정한다. 합의가 없으면 요구사항 없는 항목이 결함으로 올라간다.
QA가 실제로 점검하는 항목
저장소 — 기기에 무엇이 남는가
앱을 정상 시나리오로 한 바퀴 돌린 뒤, 앱이 만든 파일을 전수 조사하는 것이 출발점이다. 자사 앱의 디버그 빌드, 자사가 관리하는 테스트 기기에서만 수행한다.
점검 항목:
- 앱 전용 저장 영역 — SQLite DB, SharedPreferences/UserDefaults, 캐시·로그 파일에 토큰·주민등록번호·카드번호가 평문으로 있는가
- 외부/공유 저장 영역 — 다른 앱이 읽을 수 있는 위치에 첨부파일·영수증 이미지를 두는가
- 키 저장 — 대칭키·리프레시 토큰을 소스에 하드코딩하거나 평문 파일에 두는가, Keystore/Keychain을 쓰는가
- 백업 포함 여부 — 자동 백업 대상에 민감 파일이 들어가는가. Android는 매니페스트의 백업 설정과 백업 규칙, iOS는 파일별 백업 제외 속성이 판정 근거다. 백업은 기기를 벗어나는 경로 이므로 저장소 점검의 일부로 본다
- 로그 — 릴리스 빌드에서 요청/응답 본문이나 토큰을 로그로 남기는가. 크래시 리포터에 붙는 첨부도 같이 본다
- 키보드 캐시·클립보드 — 카드번호·계좌번호 입력 필드가 자동완성/예측 입력 대상인가
판정 기준은 세 질문으로 정한다. 발견된 값이 그 자체로 인증을 대체하는가, 유출되면 다른 계정에도 쓸 수 있는가, 기기 잠금이 풀린 상태만 전제하는가.
통신 — 인증서 검증과 피닝
- 평문 통신이 남아 있는가 — 이미지·광고·업데이트 체크 같은 부수 요청이 HTTP로 나가는 경우가 흔하다. Android는 네트워크 보안 설정, iOS는 ATS 예외 목록을 같이 본다
- 서버 인증서 검증을 끄지 않았는가 — 개발 편의로 넣은 "모든 인증서 신뢰" 코드가 릴리스에 남는 것이 가장 자주 나오는 결함이다. 코드 검색과 실측을 둘 다 한다
- 호스트네임 검증 — 인증서가 유효하지만 호스트가 다른 경우를 거부하는가
- 인증서 피닝 — 적용했다면 ① 핀이 실제로 동작하는가(테스트용 프록시 CA를 신뢰 저장소에 넣어도 연결이 끊기는가), ② 핀 교체 경로가 있는가, ③ 백업 핀이 있는가를 본다
피닝은 양면성이 있다. 보안은 올라가지만 인증서 갱신 시점에 앱이 전부 죽는 사고 의 원인이 된다. 그래서 피닝 검증에는 "핀 만료·교체 리허설"이 반드시 들어간다.
인증·세션
레슨 2의 내용이 모바일 문맥으로 옮겨오는 부분만 본다.
- 생체 인증의 위치 — 생체 인증 성공이 곧 서버 세션 발급으로 이어지는가, 아니면 기기에 보관된 자격을 잠금 해제하는 용도인가. 전자라면 클라이언트 결과를 서버가 신뢰하는 구조다
- 로컬 PIN·패턴 — 시도 횟수 제한과 잠금이 서버 검증 없이 클라이언트에만 있는가
- 로그아웃·재설치 — 로그아웃 시 서버 세션이 실제로 무효화되는가, 재설치 후에도 이전 세션이 살아 있는가
플랫폼 상호작용
모바일에만 있는 표면이다. 여기서 나오는 결함은 웹 체크리스트에 항목 자체가 없다.
- 딥링크·커스텀 스킴 — 외부에서 호출되는 진입점은 인증되지 않은 입력 이다. 파라미터로 내부 화면·내부 동작을 지정할 수 있는가, 링크 호출만으로 상태를 바꾸는 동작이 실행되는가
- IPC 노출 — Android라면 export 여부와 권한 설정, 즉 다른 앱이 부를 수 있는 컴포넌트가 의도된 것뿐인지 확인한다. iOS라면 앱 그룹·공유 컨테이너·확장(extension) 경계를 본다
- WebView — 로컬 파일 접근, 자바스크립트 브릿지로 노출된 네이티브 함수, 원격 콘텐츠 로드 허용 범위
- 화면 노출 — 앱 전환 시 남는 스냅샷에 카드번호·잔액이 찍히는가, 민감 화면에서 스크린샷/화면 녹화를 어떻게 다루는가, 알림 미리보기에 본문이 그대로 나오는가
m52와의 경계 — m52의 권한·프라이버시 레슨(s5-m52-l02)은 권한 요청 UX와 스토어 정책 준수, 딥링크 레슨(s5-m52-l03)은 기능이 의도대로 동작하는지 를 본다. 이 레슨은 같은 표면을 보안 검증 기준 으로 본다. 딥링크를 예로 들면 m52는 "링크가 올바른 화면을 여는가", 여기는 "링크로 열려서는 안 되는 화면이 열리는가"다.
코드와 의존성
서드파티 SDK가 수집·전송하는 데이터(광고·분석 SDK가 동의 없이 식별자를 보내는 사례가 나온다), 취약 버전 라이브러리 포함 여부, 디버그 플래그·테스트 엔드포인트의 릴리스 잔존 여부를 본다.
코드 보호의 한계 — 무엇이 근본 대응이 아닌가
이 절이 이 레슨에서 가장 자주 오해되는 부분이다.
난독화, 루팅/탈옥 탐지, 에뮬레이터 탐지, 디버거 탐지, 무결성 검증은 모두 공격 비용을 올리는 장치 다. 기기를 통제하는 공격자에게는 결국 우회될 수 있다는 전제가 MASVS-RESILIENCE의 설계 의도에 들어 있다. 그래서 다음 판단은 틀렸다.
| 틀린 판단 | 왜 틀렸나 | 올바른 대응 |
|---|---|---|
| "난독화했으니 앱에 API 키를 넣어도 된다" | 문자열은 실행 시점에 메모리에 있다 | 키를 앱에 넣지 않는다. 서버 중계 또는 단기 토큰 |
| "루팅 탐지가 있으니 로컬 검사를 신뢰해도 된다" | 탐지는 우회된다 | 권한·금액 판정은 서버에서 |
| "무결성 검증이 있으니 클라이언트 계산 결과를 그대로 저장한다" | 변조된 클라이언트도 유효한 요청을 보낼 수 있다 | 서버가 재계산하거나 최소한 검증 |
| "화면 캡처 차단을 켰으니 민감 정보 노출은 해결됐다" | 다른 기기로 촬영하면 끝이다 | 애초에 전체 값을 표시하지 않는다(마스킹) |
QA가 보고서에 쓸 문장은 이렇게 된다. "루팅 탐지 우회 가능"은 그 자체로 높은 심각도가 아니다. 문제가 되는 것은 "루팅 탐지를 우회하면 서버가 막지 않는 동작이 성공한다" 는 사실이다. 전자는 RESILIENCE 항목의 관찰이고, 후자는 AUTH 또는 서버 측 인가 결함이다. 두 개를 분리해서 쓰면 개발팀이 무엇을 고쳐야 하는지가 분명해진다.
거꾸로 코드 보호를 요구사항으로 명시한 경우(MAS-R 프로파일, 계약·규제 요구)에는 그것이 동작하는지 확인하는 것도 QA의 일이다. 이때 확인 대상은 "우회가 불가능한가"가 아니라 "선언한 방어가 켜져 있고, 켜진 상태에서 정상 기능이 깨지지 않는가" 다. 후자를 빼먹으면 보호 기능이 정상 사용자를 막는 사고가 난다 — 기업용 MDM 기기가 루팅으로 오탐되는 사례가 대표적이다.
점검 항목을 케이스로 옮기는 형식
MASVS 그룹을 그대로 테스트 케이스로 쓸 수는 없다. 아래 형식으로 한 단계 내린다.
제어 그룹 MASVS-PLATFORM
점검 질문 외부 딥링크로 인증이 필요한 화면을 열 수 있는가
대상 myapp://order/detail?id=... (문서화된 스킴 전체)
사전 조건 로그아웃 상태 / 다른 계정 로그인 상태 2가지
수행 자사 테스트 기기에서 링크 호출
기대 로그인 화면으로 유도되고, 대상 리소스는 서버 인가로 차단된다
판정 근거 화면 결과 + 서버 응답 코드 + 서버 접근 로그
증거 기기 화면 녹화, 프록시 기록, 서버 로그 타임스탬프
연결 MASTG 해당 테스트 ID(원문 확인)증거 세 줄(기기·네트워크·서버)을 항상 같이 남긴다. 기기 화면만 있으면 "서버가 막았는지 앱이 막았는지"를 구분할 수 없고, 그 구분이 심각도를 정한다.
실무에서 왜 필요한가
첫째, 모바일 결함은 핫픽스가 느리다. 서버는 롤백하면 끝이지만 앱은 스토어 심사와 사용자 업데이트를 거친다. 강제 업데이트를 걸어도 며칠이 걸린다. 릴리스 전 점검의 가치가 웹보다 크다.
둘째, 스토어와 규제가 이 항목들을 직접 묻는다. 개인정보 처리 방침과 실제 SDK 전송 내역이 다르면 심사에서 걸린다. 국내에서는 개인정보 보호 요구가 앱 저장·전송 항목과 그대로 연결된다(레슨 6).
셋째, 스캐너만으로는 절반밖에 못 본다. 모바일 자동 진단 도구는 매니페스트 설정, 하드코딩 문자열, 취약 API 호출 같은 정적 신호를 잘 찾지만, 딥링크로 열리는 화면이 인가를 확인하는지, 로그아웃이 서버 세션을 죽이는지 같은 동적·논리적 항목은 사람이 시나리오를 만들어야 한다. 그 부분이 QA가 대체 불가능한 영역이고, 발견을 제어 그룹별로 정리해 두면 조치도 빨라진다.