Back
Featured image of post Deeplink 취약점

Deeplink 취약점

딥링크(Deep Link?)란?

딥링크는 URL 링크의 일종입니다. 웹이 아닌 앱 내의 특정 페이지로 직접 연결시킵니다. 딥링크는 커스텀 URL 스킴(iOS Universal Link)이나 Intent URL(Android 기기)을 사용하여 설치된 앱을 시작합니다. 모바일 딥링크는 일반적으로 Scheme://Path의 형태를 갖습니다. 웹에서 사용되는 http://, https://와는 다르게 모바일 어플리케이션마다 각자 생성한 프로토콜을 사용하고 있어 검증이 미흡한 경우 취약점이 발생 가능합니다.

[deep링크 구성 예시]
schema://host.name/path/to/endpoint?

딥링크(Deeplink)의 취약점

개발자가 생성한 딥링크에 대한 검증이 없을 경우 외부 악의적인 사용자가 임의로 조적이 가능합니다. 관련 앱 자바 스크립트가 권한인증 없이 자동으로 실행시킬수 있으며, 의도치 않은 악성 사이트에 접속시켜 개인정보(카드,비밀번호, 주민번호 등)가 유출 될 수 있습니다.

  1. 테스트 용 앱 https://github.com/optiv/InsecureShop

  2. AndroidManifest.xml 분석 InsecureShop.apk 파일을 디컴파일 해보면 AndroidManifest.xml 파일에서 data 태그에 host가 com.insecureshop, scheme이 insecureshop으로 정의된 것을 알 수 있습니다.

  3. com.insecureshop.WebViewActivity 분석
    아래 코드를 분석해 보면 /web, /webview 가 있는지 확인하고 url 파라미터 값을 data에 저장합니다. 그리고 data가 null이 아닌경우 url을 호출하는 것을 확인할 수 있습니다.

  4. 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)의 취약점 조치방안

  1. 딥링크 URI 파싱 시 취약점 함수 사용 금지
    (1) 취약점
    substring 메소드로 받은 딥링크 파라미터는 사용자 어플리케이션 자바스크립트 권한을 받아 결과 값(어플리케이션 내 카드번호, 주소 등 민감한 개인 정보)을 공격자 사이트에 반환
    (2) 조치방안
    URI 파싱 시 getHost, substring, split 함수를 통해 필터링 없이 값을 가져오지 말아야 하며, getQueryParameter 등의 함수를 활용하여 사전에 정의된 인자 값을 파싱하도록 권장
    ※ 직접 동적으로 파싱하지 않도록 개발
  Uri data = intent.getdata();
  data.getQueryParameter(type); data.getQueryParameter(actionUrl);
  1. 인가된 URI에만 자바인터페이스 권한 부여 (1) 취약점 외부 사이트에서 접속 시 검증 없이 자바인터페이스 권한을 줄 때 이를 악용하여 개인정보 유출(세션값, 전화번호, 카드번호, 주소 등) (2) 조치방안 외부 사이트에서 자바인터페이스 권한을 허용하여 세션, 위치정보 등 개인정보가 유출되지 않도록 제한 필요 ex) 외부 사이트에서의 임의 스크립트 실행 방지 구문 예시코드

      if(HPCUtil.Attack(uri)){ 
        webview.getSettings().setJavaScriptEnabled(false);
        //자바스크립트 허용하지 않음 
        webview.removeJavascriptInterface(SCRIPT_NAME);
        //자바인터페이스 객체 제거 
      }
      layoutWebview.loadurl(uri);
    
  2. 도메인 검증을 이용한 우회 방지
    (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/ // 서브 도메인으로 우회 어려움
  1. 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

comments powered by Disqus