딥링크(Deep Link?)
딥링크(Deep Link?)란?
딥링크는 URL 링크의 일종입니다. 웹이 아닌 앱 내의 특정 페이지로 직접 연결시킵니다. 딥링크는 커스텀 URL 스킴(iOS Universal Link)이나 Intent URL(Android 기기)을 사용하여 설치된 앱을 시작합니다. 모바일 딥링크는 일반적으로 Scheme://Path의 형태를 갖습니다. 웹에서 사용되는 http://, https://와는 다르게 모바일 어플리케이션마다 각자 생성한 프로토콜을 사용하고 있어 검증이 미흡한 경우 취약점이 발생 가능합니다.
[deep링크 구성 예시]
schema://host.name/path/to/endpoint?
딥링크(Deeplink)의 취약점
개발자가 생성한 딥링크에 대한 검증이 없을 경우 외부 악의적인 사용자가 임의로 조적이 가능합니다. 관련 앱 자바 스크립트가 권한인증 없이 자동으로 실행시킬수 있으며, 의도치 않은 악성 사이트에 접속시켜 개인정보(카드,비밀번호, 주민번호 등)가 유출 될 수 있습니다.
딥링크(Deeplink) 취약점 예시
-
AndroidManifest.xml 분석 InsecureShop.apk 파일을 디컴파일 해보면 AndroidManifest.xml 파일에서 data 태그에 host가 com.insecureshop, scheme이 insecureshop으로 정의된 것을 알 수 있습니다.
-
com.insecureshop.WebViewActivity 분석
아래 코드를 분석해 보면 /web, /webview 가 있는지 확인하고 url 파라미터 값을 data에 저장합니다. 그리고 data가 null이 아닌경우 url을 호출하는 것을 확인할 수 있습니다. -
POC 코드 작성 및 실행 확인
(1) POC 코드 작성#1 deeplink 작성 insecureshop://com.insecureshop/web?url=www.google.com #2 adb 실행 명령어 adb shell am start -W -a android.intent.action.VIEW -d "insecureshop://com.insecureshop/web?url=www.google.com/"
(2) 앱 실행 확인
(3) adb 명령어 실행
(4) 웹 이동 확인
[번외] 딥링크 실행 방법
(1) 딥링크 테스트 사이트 이용
(2) 단말기 내에서 html 파일 생성 후 a 태그로 딥링크를 작성하여 요청
(3) adb 명령어 이용( adb shell am start -W -a android.intent.action.VIEW -d “deeplink” 패키지명
ex) adb shell am start -W -a android.intent.action.VIEW -d “app://deeplink/load.jsp?Url=javascript:Android.getGPSLocation()”
딥링크(Deeplink)의 취약점 조치방안
- 딥링크 URI 파싱 시 취약점 함수 사용 금지
(1) 취약점
substring 메소드로 받은 딥링크 파라미터는 사용자 어플리케이션 자바스크립트 권한을 받아 결과 값(어플리케이션 내 카드번호, 주소 등 민감한 개인 정보)을 공격자 사이트에 반환
(2) 조치방안
URI 파싱 시 getHost, substring, split 함수를 통해 필터링 없이 값을 가져오지 말아야 하며, getQueryParameter 등의 함수를 활용하여 사전에 정의된 인자 값을 파싱하도록 권장
※ 직접 동적으로 파싱하지 않도록 개발
Uri data = intent.getdata();
data.getQueryParameter(“type”); data.getQueryParameter(“actionUrl”);
-
인가된 URI에만 자바인터페이스 권한 부여 (1) 취약점 외부 사이트에서 접속 시 검증 없이 자바인터페이스 권한을 줄 때 이를 악용하여 개인정보 유출(세션값, 전화번호, 카드번호, 주소 등) (2) 조치방안 외부 사이트에서 자바인터페이스 권한을 허용하여 세션, 위치정보 등 개인정보가 유출되지 않도록 제한 필요 ex) 외부 사이트에서의 임의 스크립트 실행 방지 구문 예시코드
if(HPCUtil.Attack(uri)){ webview.getSettings().setJavaScriptEnabled(false); //자바스크립트 허용하지 않음 webview.removeJavascriptInterface(SCRIPT_NAME); //자바인터페이스 객체 제거 } layoutWebview.loadurl(uri);
-
도메인 검증을 이용한 우회 방지
(1) 취약점
도메인 뒤 또는 앞에 attacker.net과 같은 서브 도메인을 추가하여 실질적으로 관련 앱의 권한을 받음
(2) 조치방안
- 하드코딩 된 일부 string 구문 비교를 통해 파싱할 경우 취약점을 유발할 수 있으므로 검증된 도메인에서 함수 호출, 정보 반환, 웹뷰를 출력하도록 검증된 도메인 리스트 설정 필요
▶ 검증된 도메인 리스트 설정 및 uri.startsWith 함수를 통해 URI 확인
ex1) uri.startswith 사용예시
uri=“https://www.origin.com/”
uri.startsWith(“https://www.origin.com/”)//true
uri.startsWith(“https://www.attacker.net/”)//false
ex2) whitedomainlist를 활용한 startsWith 사용예시
public static boolean whitedomainlist(String str) {
for(String startsWith : whitedomainlist) {
if(str.startsWith(startsWith))) {
return true;
}
}
return false;
}
- 서브 도메인 악용을 막기 위해 슬래쉬(/)로 끝나도록 명확한 검증 도메인명 작성
[예시]
https://www.orgin.com // 해당 도메인으로 검증할 경우 우회 가능
https://www.origin.com/ // 서브 도메인으로 우회 어려움
- URI.parse 함수 사용 시 특수문자 필터링 필요
(1) 취약점
URI.parse 함수 사용 시 특정 특수문자 문자열을 삽입하여 URI 인증을 우회, 앱의 권한을 받음
(2) 조치방안- 필터링을 통해 우회하지 못하도록 특수문자 검증 등의 조치 권장
ex) var Filter = @#$%&
return uri.replaceAll(Filter,“”); - URI.parse 함수는 getdata 등의 대체 함수 사용 권장
ex) Uri uri = intent.getdata();
- 필터링을 통해 우회하지 못하도록 특수문자 검증 등의 조치 권장
출처 및 참고자료
<안드로이드 어플리케이션 딥링크(Deeplink) 취약점관련 보안조치안내 - 한국인터넷 진흥원>
https://jacobwoo.tistory.com/entry/%EB%94%A5%EB%A7%81%ED%81%ACDeeplink%EB%9E%80
https://jdh5202.tistory.com/954
https://prod.velog.io/@silver35/Android-Open-redirect-vulnerability-Using-Deeplink