OWASP 카테고리: MASVS-PLATFORM: 플랫폼 상호작용
개요
JavaScript 브리지라고도 하는 네이티브 브리지는
WebView와 네이티브 Android 코드 간의 통신을 용이하게 하며,
addJavascriptInterface
메서드 사용 이렇게 하면
WebView와 Android에서 실행되는 JavaScript 코드 간의 통신
애플리케이션의 Java 코드를
가져올 수 있습니다 addJavascriptInterface
메서드는 Java 객체를 모든 WebView 프레임에 노출하며, 모든 프레임은 객체 이름에 액세스하고 객체의 메서드를 호출할 수 있습니다. 그러나 애플리케이션이
WebView 내에서 호출 프레임의 출처를 확인하여 보안을 강화합니다.
문제가 발생할 수 있음을 명심해야 합니다.
또한 네이티브 브리지를 사용하여 HTML 메시지 채널을 구현할 수 있습니다.
Android의 WebViewCompat.postWebMessage
또는
JavaScript와 통신하기 위한 WebMessagePort.postMessage
Window.postMessage
: WebViewCompat.postWebMessage
및
WebMessagePort.postMessage
은(는) 다음을 통해 전송된 JavaScript 메시지를 수락할 수 있습니다.
Window.postMessage
는 WebView 내에서 실행됩니다.
네이티브 브리징과 관련된 여러 위험이 있습니다.
- JavaScriptInterface 기반 브리지:
<ph type="x-smartling-placeholder">
- </ph>
addJavascriptInterface
메서드는 제공된 Java 객체를 iframe을 포함한 WebView의 모든 프레임에 삽입합니다. 즉, 합법적인 웹사이트에 프레임을 삽입하는 악의적인 서드 파티의 공격에 취약합니다. API 수준 16 이하를 대상으로 하는 애플리케이션은 특히 이 메서드는 JavaScript가 호스트를 제어하도록 허용하는 데 사용할 수 있기 때문에 애플리케이션입니다.- 네이티브 브리지 지원 WebView에 신뢰할 수 없는 사용자가 제공한 콘텐츠를 반영하면 교차 사이트 스크립팅(XSS) 공격이 가능합니다.
- MessageChannel 기반 브리지:
<ph type="x-smartling-placeholder">
- </ph>
- 메시지 채널 엔드포인트에 출처 확인이 없으면 악성 코드가 포함된 발신자를 포함한 모든 발신자의 메시지가 허용됩니다.
- 실수로 Java를 임의의 JavaScript에 노출할 수 있습니다.
영향
addJavascriptInterface
, postWebMessage
, postMessage
메서드는 다음과 같을 수 있습니다.
공격자가 자신이 제어하는 코드에 액세스하거나 이를 조작 또는 주입하기 위해 악용할 수 있습니다.
WebView로 로드하는 것입니다. 이로 인해 사용자가 악성 사이트로 리디렉션될 수 있으며,
악성 콘텐츠를 로드하거나, 사용자가 다른 사이트로 이동할 수 있는
민감한 데이터를 추출하거나 권한 상승을 달성할 수 있습니다.
위험: addJavascriptInterface 위험
WebView는 페이지 렌더링, 탐색, JavaScript 실행과 같은 브라우저의 기본 기능을 구현합니다. WebView는 애플리케이션 내에서 활동 레이아웃의 일부로 웹 콘텐츠를 표시하는 데 사용할 수 있습니다. 네이티브 구현
addJavascriptInterface
메서드를 사용하여 WebView 내에서 브리지를 연결하면
교차 사이트 스크립팅 (XSS)과 같은 보안 문제를 야기하거나, 공격자가
인터페이스 주입을 통해서 신뢰할 수 없는 콘텐츠를 찾아내고 호스트를 조작
애플리케이션을 의도하지 않은 방식으로 실행하여
호스트 애플리케이션입니다.
완화 조치
JavaScript 사용 중지
WebView에 JavaScript가 필요하지 않은 시나리오에서는
WebSettings
내의 setJavaScriptEnabled
(예:
(정적 HTML 콘텐츠 표시)가 포함되어 있습니다. 기본적으로 WebView에서는 JavaScript 실행이 사용 중지되어 있습니다.
신뢰할 수 없는 콘텐츠를 로드할 때 JavaScript 인터페이스 삭제
다음을 호출하여 JavaScript 인터페이스의 객체가 삭제되었는지 확인합니다.
신뢰할 수 없는 콘텐츠를 로드하기 전 removeJavascriptInterface
있습니다. 예를 들어 shouldInterceptRequest
호출에서 이를 실행할 수 있습니다.
Kotlin
webView.removeJavascriptInterface("myObject")
자바
webView.removeJavascriptInterface("myObject");
HTTPS를 통해서만 웹 콘텐츠 로드
신뢰할 수 없는 콘텐츠를 로드해야 하는 경우 WebView에서 웹 콘텐츠를
암호화된 연결 (일반 텍스트에 대한 Google 가이드라인 참조)
커뮤니케이션). 초기 페이지 로드 수행을 방지
다음에서 android:usesCleartextTraffic
를 false
로 설정하여 암호화되지 않은 연결
AndroidManifest
파일을 삭제하거나 네트워크 보안에서 HTTP 트래픽을 허용하지 않음
config를 참조하세요. 자세한 내용은 usesCleartextTraffic
문서를 참고하세요.
확인할 수 있습니다
XML
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
암호화되지 않은 환경에서 리디렉션과 추가 앱 탐색이 발생하지 않도록 하기 위해
loadUrl
에서 HTTP 스키마를 확인하거나
shouldInterceptRequest
:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
자바
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
신뢰할 수 없는 콘텐츠 검증
외부 링크가 WebView에 로드되면 스키마와 호스트(허용 목록 도메인)를 모두 검사합니다. 허용 목록에 없는 도메인은 기본 브라우저에서 열어야 합니다.
신뢰할 수 없는 콘텐츠를 로드하지 마세요
가능한 경우 엄격하게 범위가 지정된 URL과 앱 소유의 콘텐츠만 로드합니다. WebView에 추가하세요.
민감한 정보 노출 금지
애플리케이션에서 WebView를 사용하여 민감한 정보에 액세스하는 경우
clearCache
메서드를 사용하여 로컬에 저장된 모든 파일을 삭제합니다.
JavaScript 인터페이스입니다. no-store와 같은 서버 측 헤더를 사용하여 애플리케이션이 특정 콘텐츠를 캐시하면 안 된다는 것을 나타낼 수도 있습니다.
민감한 기능을 노출하지 마세요.
애플리케이션에 민감한 권한이 필요하거나 민감한 정보를 수집하는 경우 애플리케이션 내 코드에서 호출되고 눈에 잘 띄는 공개 문구가 사용자에게 제공되는지 확인합니다. 어떤 용도로든 JavaScript 인터페이스를 사용하지 마세요. 민감한 작업 또는 사용자 데이터를 사용할 수 있습니다
API 수준 21 이상 타겟팅
addJavascriptInterface
메서드를 사용하는 안전한 방법 중 하나는 API 수준을 타겟팅하는 것입니다.
API 수준 21에서 실행할 때만 메서드가 호출되도록 하여 버전 21 이상
또는 그 이상일 수 있습니다. API 21 이전에는 JavaScript가 리플렉션을 사용하여 공개 액세스에 액세스할 수 있었습니다.
인젝션된 객체의 필드입니다.
위험: MessageChannel 위험
postWebMessage()
및 postMessage()
에 출처 제어가 없으면 공격자가 메시지를 가로채거나 네이티브 핸들러로 메시지를 전송할 수 있습니다.
완화 조치
postWebMessage()
또는 postMessage()
설정 시 다음에서 보낸 메시지만 허용
대상 출처로 * 를 사용하지 않고 대신 신뢰할 수 있는 도메인의 경우
예상되는 전송 도메인을 명시적으로 지정해야 합니다.
리소스
- postMessage() 권장사항
- addJavascriptInterface 문서
- postMessage() 문서
- WebMessagePort.postMessage() 문서
- WebViewClient.shouldInterceptRequest 문서
- addJavascriptInterface와 관련된 보안 조언 문서
- clearCache 문서
- removeJavascript 문서
- WebView에서 JavaScript 사용 설정