본문으로 건너뛰기
고급약 40분

모바일 앱 보안 — OWASP MASVS·MASTG 기준의 검증 항목

웹 기준으로 만든 보안 체크리스트를 모바일 앱에 그대로 쓰면 절반이 헛돈다. 앱은 공격자가 통제하는 기기에서 실행되고, 저장소·딥링크·IPC 같은 플랫폼 표면을 추가로 갖는다. OWASP MASVS v2.1.0의 8개 제어 그룹과 MASTG의 관계를 정리하고, 검증 프로파일을 골라 저장소·통신·인증·플랫폼 점검 항목을 케이스로 옮긴다. 난독화·루팅 탐지가 왜 근본 대응이 아닌지도 짚는다.

  • #MASVS
  • #MASTG
  • #모바일보안
  • #인증서피닝
  • #딥링크
  • #난독화

개념

모바일 앱의 신뢰 경계는 어디에 있나

서버 애플리케이션을 검증할 때 우리는 "서버는 우리 것"이라는 가정 위에 서 있다. 모바일 앱에는 그 가정이 없다. 배포된 바이너리는 공격자가 완전히 통제하는 기기 안에서 돌아간다. 디스어셈블할 수 있고, 저장소를 열어볼 수 있고, 프로세스에 후킹할 수 있고, 시스템 시간을 바꿀 수 있다. 모바일 보안 검증의 첫 번째 원칙은 이렇게 정리된다.

클라이언트에서 수행되는 검사는 시간을 벌어주는 장치 일 뿐이고, 권한·금액·자격에 대한 판정은 서버에서만 유효하다.

그래서 점검은 두 갈래다. 서버가 제대로 판정하는지(레슨 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가 대체 불가능한 영역이고, 발견을 제어 그룹별로 정리해 두면 조치도 빨라진다.

실습 과제

모든 과제는 자사 앱의 디버그·스테이징 빌드와 자사가 관리하는 테스트 기기, 또는 의도적으로 취약하게 만든 교육용 앱(OWASP MAS 프로젝트의 학습용 앱 등) 안에서만 수행한다. 스토어에 올라간 타사 앱을 대상으로 하지 않는다.

과제 1 — 저장소·백업 전수 조사 (30분)

담당 앱의 디버그 빌드로 로그인 → 주요 기능 3개 → 로그아웃까지 한 바퀴 돈다. 그 뒤 앱이 만든 파일 목록을 뽑아 아래 표로 정리한다.

파일/키내용 요약민감도암호화백업 대상판정
높음/중간/낮음예/아니오/해당없음예/아니오결함/관찰/정상

"결함"으로 판정한 항목마다 그 값이 유출되면 공격자가 무엇을 할 수 있는지 를 한 문장으로 쓴다. 쓸 수 없다면 판정을 "관찰"로 내린다. 마지막으로 로그아웃 후에도 남아 있는 값을 별도로 표시한다.

과제 2 — 통신 검증과 피닝 교체 리허설 (30분)

스테이징 환경에서 프록시를 걸고 앱의 전체 요청 목록을 수집해 ① 평문 요청, ② 인증서 검증을 하지 않는 요청, ③ 피닝이 걸린 요청을 분류한다. 그다음 피닝이 있다면 핀 불일치 상황을 만들어 앱이 어떻게 동작하는지 기록한다 — 연결 차단인지, 무한 재시도인지, 사용자에게 무엇이라고 표시되는지, 복구 경로가 있는지. 피닝이 없다면 "도입 시 교체 절차 초안"을 대신 쓴다. 결과물은 요청 분류표 + 핀 만료 시 대응 절차 5단계다.

과제 3 — 플랫폼 표면 점검 케이스 작성 (25분)

딥링크·IPC·화면 노출 중 두 가지 표면 을 골라, 본문의 "제어 그룹 → 케이스" 형식으로 실행 가능한 케이스를 각 3개씩 만든다(총 6개). 각 케이스에 기대 결과와 증거 세 줄(기기·네트워크·서버)을 명시하고, 그중 하나는 반드시 "차단되는 것이 정상"인 음성 케이스 로 만든다. 마지막으로 회귀에 상시 포함할 것을 구분해 표시한다.

자가 체크리스트

  • MASVS와 MASTG의 역할 차이를 설명하고, 현재 판이 v2.1.0이며 프로파일을 근거와 함께 고를 수 있다
  • MASVS v2.x의 8개 제어 그룹 이름을 열거할 수 있다
  • 검증 레벨이 MASVS에서 MASTG의 테스트 프로파일(MAS-L1/L2/R)로 옮겨졌음을 안다
  • 저장소 점검에 백업·로그·클립보드·키보드 캐시를 포함한다
  • 인증서 검증·호스트네임 검증·피닝을 구분하고 피닝 교체 경로를 함께 점검한다
  • 딥링크·IPC·WebView·화면 노출을 인증되지 않은 입력 표면으로 다룬다
  • 난독화·루팅 탐지를 근본 대응이 아니라 지연 장치로 위치시킬 수 있다
  • "탐지 우회 가능"과 "우회 후 서버가 막지 않음"을 분리해 보고한다
  • 모바일 발견의 증거를 기기·네트워크·서버 세 층으로 남긴다

흔한 실수

  • 웹 체크리스트를 그대로 쓴다. 저장소·플랫폼 상호작용 항목이 통째로 빠진다. 반대로 XSS 항목에 시간을 과하게 쓴다.
  • v1.x의 V-번호를 현행 문서라고 믿는다. MASVS-V2.1 형식은 구판이다. 현행은 그룹 이름 + 번호 형식이다.
  • 디버그 빌드만 점검하고 끝낸다. 로그 노출·디버그 플래그 같은 항목은 릴리스 빌드에서 확인해야 의미가 있다. 두 빌드의 설정 차이를 표로 비교하는 것이 안전하다.
  • 한 대의 기기로 결론 낸다. OS 버전에 따라 백업 정책, 저장소 접근 제약, 스냅샷 동작이 다르다. 최소 두 버전에서 확인한다.
  • "난독화 안 됨"을 높은 심각도로 올린다. 프로파일에 R이 없으면 요구사항이 아니다. 요구사항 없는 항목을 결함으로 올리면 보고서 신뢰가 떨어진다.
  • 교육용 취약 앱에서 배운 절차를 타사 앱에 적용해 본다. 권한 범위를 벗어나면 업무가 아니다. 대상은 자사 자산과 교육용 앱뿐이다.
  • 탐지 도구 출력만 붙여 보고한다. 재현 절차와 판정 근거가 없으면 개발팀이 오탐 여부를 판단할 수 없어 처리가 멈춘다.

참고 자료

  • OWASP Mobile Application Security — MASVS·MASTG·MASWE 상위 프로젝트
  • OWASP MASVS — 8개 제어 그룹 원문
  • OWASP MASTG — 테스트 절차·기법·지식 문서, MAS 테스트 프로파일(현재 매핑은 원문 확인)
  • MASVS 릴리스 노트 — 판본 이력과 v2.0.0의 레벨 이관 배경
  • OWASP Mobile Top 10 — 인식용 목록. 검증 기준으로는 MASVS를 쓴다
  • 레슨 s5-m50-l02 — 인증·인가 우회 시나리오 설계
  • 레슨 s5-m50-l03 — API 보안 Top 10을 점검 케이스로 옮기기
  • 레슨 s5-m52-l02 · s5-m52-l03 — 권한·프라이버시와 딥링크를 기능·정책 관점에서 다루는 레슨

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

MASVS — 모바일 앱 보안 검증 표준
휴대전화 앱이 갖춰야 할 보안 요구사항을 정리한 기준.
MASTG — 모바일 앱 보안 시험 지침
위 기준을 실제로 어떻게 확인하는지 적어 둔 방법서.
OWASP — 오왁스프
웹과 앱 보안 자료를 공개로 만드는 비영리 단체. 취약점 목록과 점검 기준이 유명하다.
UI — 사용자 인터페이스
사람이 직접 보고 누르는 부분 — 화면, 버튼, 입력창.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
DB — 데이터베이스
데이터를 넣어 두고 꺼내 쓰는 저장소. 보통 표 여러 개가 서로 연결된 형태다.
HTTP — 하이퍼텍스트 전송 규약
웹에서 요청과 응답을 주고받는 약속. "무엇을 달라"고 보내면 "여기 있다" 또는 "그런 건 없다"가 돌아온다.
컨테이너 — 컨테이너
이 커리큘럼에서 두 가지로 쓰인다. ① 프로그램과 그것을 돌리는 데 필요한 것들을 한 상자에 담아, 어느 컴퓨터에서나 똑같이 돌아가게 만든 것 ② 화면에서 여러 요소를 하나로 묶는 바깥 틀. 서버·배포 이야기면 ①, 화면·접근성 이야기면 ②다.
UX — 사용자 경험
쓰는 사람이 느끼는 전체 느낌 — 빠른가, 헷갈리지 않는가, 실수해도 되돌릴 수 있는가.
SDK — 소프트웨어 개발 도구 모음
어떤 기능을 쓰려고 할 때 필요한 도구와 코드를 묶어 둔 꾸러미.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
XSS — 크로스 사이트 스크립팅
입력창에 넣은 글자가 화면에서 명령으로 실행되게 만드는 공격.

이 레슨에 나온 나머지 1개를 포함해 용어집 전체 보기