Category Archives: Android

Mac Sierra 업그레이드 후 ADB 연결이 간헐적으로 끊어지는 문제 해결하기

이번에 macOS가 Sierra(10.12)로 업데이트 되면서 이상하게도 ADB가 정상적으로 동작하지 않는 문제가 있었습니다. 그럴때마다 Android 디바이스를 재연결 하거나 ADB Server를 재시작하는 식으로 문제를 해결해 왔습니다만 좀 더 근본적으로 이 문제를 해결할 수 있는 방법이 있어서 내용을 정리합니다.

우선 이는 Android Studio 2.2가 배포되던 시기에 함께 배포되던 Android SDK Platform Tools 에 존재했던 버그때문에 발생한 문제입니다. 이는 [참고URL]와 같이 해결 되었으며 Android SDK Platform Tools 버전 24.0.4 이후에 적용되었습니다.

%e1%84%89%e1%85%b3%e1%84%8f%e1%85%b3%e1%84%85%e1%85%b5%e1%86%ab%e1%84%89%e1%85%a3%e1%86%ba-2016-11-06-%e1%84%8b%e1%85%a9%e1%84%92%e1%85%ae-1-24-23

이 글을 작성하는 현재 시점에서는 버전이 25까지 올라갔군요. 하지만 저의 경우에는 이렇게 버전업그레이드를 했음에도 계속해서 문제가 발생하였습니다. 심지어 ADB의 오류 메시지로는 다음과 같은 메시지가 출력되었습니다.

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
error: no devices/emulators found
error: no devices/emulators found

...

error: device unauthorized.
This adb server's $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.

이와 같은 문제는 다음의 과정을 통해 해결할 수 있었습니다.

1. Android 디바이스의 연결을 해제 합니다. 간단하게 USB 케이블을 뽑으시면 됩니다.

2. ADB Server를 종료합니다.

$ adb kill-server

3. Android 설정 파일이 존재하는 디렉토리로 이동합니다.

$ cd ~/.android

4. 디렉토리 안에 존재하는 adbkey 및 adbkey.pub 파일을 삭제합니다.

$ rm adbkey*

5. ADB Server를 재시작 합니다.

$ adb start-server

6. Android 디바이스를 다시 연결합니다. 이후 다시 신뢰하는 디바이스로 연결하겠냐는 팝업이 뜨게 되는데 다시 등록해 주시면 adbkey 파일이 재생성됩니다.

위와 같은 작업을 거치고 나면 연결이 끊어지지 않고 정상적으로 동작하는 것을 확인할 수 있습니다.

참고 :

Google Play 안전하지 않은 onReceivedSslError 경고 대응하기

logo-google-play-vetor

요즘 들어 구글플레이에 등록한 앱의 코드 레벨의 검증이 수행되고 있나 봅니다. 이번에는 웹뷰를 구현할때에 필히 사용되는 WebViewClient 클래스의 onReceivedSslError 의 처리가 안전하지 않다는 경고가 뜨는 사례가 발생하고 있는데요. 현재 이부분을 정상적으로 처리하지 않은 앱의 경우 업데이트가 이루어지지 않고 있습니다. 이 오류의 대상자가 되면 받는 메일의 내용은 다음과 같습니다.

애플리케이션에 WebViewClient.onReceivedSslError 핸들러가 안전하지 않은 방식으로 구현되었습니다. 특히 해당 구현은 모든 SSL 인증서 확인 오류를 무시하여 앱을 중개인 공격에 취약하게 만듭니다. 공격자는 영향을 받은 WebView의 콘텐츠를 변경하고, 전송된 데이터(예: 로그인 사용자 인증 정보)를 읽고, 자바스크립트를 사용해 앱 내부에서 코드를 실행할 수 있습니다.

SSL 인증서를 제대로 확인하려면 서버에서 제공하는 인증서가 요구사항을 충족할 때마다 코드를 변경하여 SslErrorHandler.proceed()을(를) 호출하고 그렇지 않으면 SslErrorHandler.cancel()을(를) 호출합니다. 대상 앱 및 클래스를 포함하는 이메일 알림이 개발자 계정 주소로 전송됩니다.

최대한 빨리 취약점을 해결하고 업그레이드된 APK의 버전 번호를 올리시기 바랍니다. SSL 오류 핸들러에 대한 자세한 내용은 개발자 도움말 센터의 Google 문서를 참조하시기 바랍니다. 다른 기술 관련 질문은https://www.stackoverflow.com/questions에 게시하고 ‘android-security’ 및 ‘SslErrorHandler’ 태그를 사용하세요. 이 문제에 대한 책임이 있는 타사 라이브러리를 사용하는 경우 타사에 문의하여 이 문제를 해결하시기 바랍니다.

제대로 업그레이드되었는지 확인하려면 업데이트된 버전을 개발자 콘솔에 업로드하고 5시간 후에 다시 확인하세요. 앱이 제대로 업그레이드되지 않은 경우 경고 메시지가 표시됩니다.

이러한 특정 문제가 WebView SSL을 사용하는 일부 앱에는 영향을 미치지 않을 수 있으나 모든 보안 패치를 최신 상태로 유지하는 것이 좋습니다. 사용자를 보안 위험에 노출시키는 취약점을 보유하고 있는 앱은 Google의 악의적 행위 정책 및 개발자 배포 계약의 섹션 4.4를 위반하는 것으로 간주될 수 있습니다.

게시된 모든 앱이 개발자 배포 계약 및 개발자 프로그램 정책을 준수하는지 확인하시기 바랍니다. 궁금한 점이나 우려되는 사항이 있으면 Google Play 개발자 도움말 센터를 통해 지원팀에 문의하세요.

혹은 영어 버전의 경고 메일의 내용은 다음과 같습니다.

Security alert Your application has an unsafe implementation of the WebViewClient.onReceivedSslError handler. Specifically, the implementation ignores all SSL certificate validation errors, making your app vulnerable to man-in-the-middle attacks. An attacker could change the affected WebView’s content, read transmitted data (such as login credentials), and execute code inside the app using JavaScript.

To properly handle SSL certificate validation, change your code to invoke SslErrorHandler.proceed() whenever the certificate presented by the server meets your expectations, and invoke SslErrorHandler.cancel() otherwise. An email alert containing the affected app(s) and class(es) has been sent to your developer account address.

Please address this vulnerability as soon as possible and increment the version number of the upgraded APK. For more information about the SSL error handler, please see our documentation in the Developer Help Center. For other technical questions, you can post to https://www.stackoverflow.com/questions and use the tags “android-security” and “SslErrorHandler.” If you are using a 3rd party library that’s responsible for this, please notify the 3rd party and work with them to address the issue.

To confirm that you’ve upgraded correctly, upload the updated version to the Developer Console and check back after five hours. If the app hasn’t been correctly upgraded, we will display a warning.

Please note, while these specific issues may not affect every app that uses WebView SSL, it’s best to stay up to date on all security patches. Apps with vulnerabilities that expose users to risk of compromise may be considered dangerous products in violation of the Content Policy and section 4.4 of the Developer Distribution Agreement.

Please ensure all apps published are compliant with the Developer Distribution Agreement and Content Policy. If you have questions or concerns, please contact our support team through the Google Play Developer Help Center.

문제가 되는 코드는 WebViewClient를 구현한 다음과 같은 코드입니다. SSL 오류가 발생하면 묻지도 따지지도 않고 그것을 수용하는것을 확인하실 수 있습니다.

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  handler.proceed();
}

원래는 이곳에 이 유효하지 않은것으로 판단되는 인증서가 문제가 없는지 판단하고 문제가 없을 경우 proceed()를 호출하거나 아닌 경우 cancel()을 호출하도록 처리해 주시면 됩니다. 이 판단을 하는 부분을 어떻게 구현할지는 각 앱마다 혹은 회사마다 다르겠지만 스택오버플로우에서 좋은 예를 발견하였습니다.

invalid_ssl_certificate_theeye

위의 스크린샷은 웹브라우저에서 유효하지 않은 인증서를 가진 HTTPS 홈페이지에 진입할 때 볼 수 있는 경고입니다. 여기에 주목할 부분은 “안전하지 않음(으)로 이동”이라는 문구인데요. 안전하지 않지만 유저가 진입할지 말지를 결정할 수 있게 함으로써 브라우저의 책임을 다했다는 것일까요?

마찬가지로 Android에서도 유효하지 않은 인증서로 판단되었을 경우 유저에게 직접 물어보면 됩니다.

@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
  final AlertDialog.Builder builder = new AlertDialog.Builder(this);
  builder.setMessage(R.string.notification_error_ssl_cert_invalid);
  builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
      handler.proceed();
    }
  });
  builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
      handler.cancel();
    }
  });
  final AlertDialog dialog = builder.create();
  dialog.show();
}

R.string.notification_error_ssl_cert_invalid 에는 유효하지 않은 사이트에 진입할것인지 물어보는 글이 들어가 있으면 되겠네요. 이와 같은 대응을 한 뒤 버전을 업그레이드 하여 구글 플레이에 등록하게 되면 5시간정도 뒤에 해당 경고가 사라지게 됩니다.

참고 : http://stackoverflow.com/questions/36050741/webview-avoid-security-alert-from-google-play-upon-implementation-of-onreceiveds