내부 콘텐츠와 인증 페이지, 외부 사이트, 앱 전용 스킴을 나눠 보안과 사용자 흐름을 함께 지키는 방법을 정리합니다. 운영 단계에서 판단의 출발점은 ‘신뢰한 내부 웹 경로’입니다. 앱이 소유하고 검증한 HTTPS 호스트와 필요한 경로만 WebView 안에서 엽니다. 호스트 문자열의 부분 일치가 아니라 정규화된 URL을 정확히 비교합니다.
이 글의 범위
실제 경험이나 측정 결과를 가정하지 않고, 공식 문서로 확인 가능한 개념과 적용 순서를 일반 가이드로 설명합니다. 제품 버전과 서비스 정책은 바뀔 수 있으므로 적용 전 연결된 공식 문서를 다시 확인하세요.
| WebView 외부 링크를 안전하게 처리하는 분기 기준 핵심 판단 흐름 설명용 개념도 |
그림 1. WebView 외부 링크를 안전하게 처리하는 분기 기준의 핵심 판단 순서를 정리한 설명용 개념도입니다. 실제 서비스 화면, 운영 로그 또는 측정 결과가 아닙니다.
링크 목적에 따라 나누는 처리 정책
신뢰한 내부 웹 경로
앱이 소유하고 검증한 HTTPS 호스트와 필요한 경로만 WebView 안에서 엽니다. 호스트 문자열의 부분 일치가 아니라 정규화된 URL을 정확히 비교합니다.
외부 웹사이트
사용자가 출처 전환을 인지할 수 있게 기본 브라우저나 Custom Tab으로 엽니다. 임의 사이트에 앱의 쿠키나 JavaScript 브리지를 노출하지 않습니다.
앱 전용 스킴
tel, mailto와 승인한 딥링크만 허용 목록으로 처리합니다. 알 수 없는 scheme을 그대로 Intent에 넘기지 않습니다.
새 창 요청
target=_blank와 window.open도 동일한 URL 검증기를 거쳐야 합니다. 새 WebView를 무조건 생성하면 정책을 우회할 수 있습니다.
파일과 브리지
필요하지 않은 파일 접근과 JavaScript 인터페이스는 끕니다. 신뢰하지 않은 콘텐츠와 강한 네이티브 기능을 같은 WebView에 두지 않습니다.
도구보다 먼저 볼 기준
WebView 링크 정책은 탐색 편의 기능이 아니라 신뢰 경계를 정하는 보안 설계입니다. ‘신뢰한 내부 웹 경로’에서 시작해 ‘외부 웹사이트’와의 경계를 정하면 구현할 범위와 실패했을 때 확인할 지점을 구분하기 쉬워집니다.
URL 분기기를 만드는 순서
- 허용할 scheme과 내부 HTTPS 호스트·경로를 명시합니다.
- URL을 파싱하고 정규화한 뒤 문자열 접두사 대신 구성 요소를 비교합니다.
- 내부·외부·앱 기능·거절의 네 결과로 분류합니다.
- 일반 이동과 새 창, 리디렉션 모두 같은 분류기를 사용합니다.
- 피싱 형태의 유사 호스트와 인코딩된 URL을 테스트합니다.
변경 전 체크 포인트
| 확인 항목 | 질문 |
|---|---|
| 첫 기준: 신뢰한 내부 웹 경로 | 변경 전에 전제와 목적을 확인했는가? |
| 분리 대상: 외부 웹사이트 | 다른 책임과 섞이지 않게 경계를 정했는가? |
| 피할 패턴: example.com 문자열이 포함되면 내부 URL로 허용하기 | 본문에서 경고한 패턴이 남아 있지 않은가? |
| 오류와 복구 | 정상 경로뿐 아니라 실패와 되돌리기도 확인했는가? |
WebView 신뢰 경계를 무너뜨리는 설정
- example.com 문자열이 포함되면 내부 URL로 허용하기
- 모든 링크를 같은 WebView와 같은 쿠키 범위에서 열기
- file 접근과 범용 파일 URL 접근을 이유 없이 켜기
- target=_blank 처리를 별도 검증 없이 구현하기
결론
WebView 링크 정책은 탐색 편의 기능이 아니라 신뢰 경계를 정하는 보안 설계입니다. URL을 구조적으로 검증하고 외부 웹과 앱 기능을 분리하면 사용자의 맥락을 유지하면서도 불필요한 권한 노출을 줄일 수 있습니다.