I. 代码实现

1.1 异常捕获处理

1.1.1 【必须】序列化异常捕获

对于通过导出组件 intent 传递的序列化对象,必须进行 try…catch 处理,以避免数据非法导致应用崩溃。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. try {
  4. Intent mIntent = getIntent();
  5. //String msg = intent.getStringExtra("data");
  6. Person mPerson = (Person)mIntent.getSerializableExtra(ObjectDemo.SER_KEY)
  7. //textView.setText(msg);
  8. } catch (ClassNotFoundException exp) {
  9. // ......
  10. }
  11. }
  12. }

1.1.2 【必须】NullPointerException 异常捕获

对于通过 intent getAction 方法获取数据时,必须进行 try…catch 处理,以避免空指针异常导致应用崩溃。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. try {
  4. Intent mIntent = getIntent();
  5. if mIntent.getAction().equals("StartNewWorld") {
  6. // ......
  7. }
  8. // ......
  9. } catch (NullPointerException exp) {
  10. // ......
  11. }
  12. }
  13. }

1.1.3 【必须】ClassCastException 异常捕获

对于通过 intent getSerializableExtra 方法获取数据时,必须进行 try…catch 处理,以避免类型转换异常导致应用崩溃。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. try {
  4. Intent mIntent = getIntent();
  5. Person mPerson = (Person)mIntent.getSerializableExtra(ObjectDemo.SER_KEY)
  6. // ......
  7. } catch (ClassCastException exp) {
  8. // ......
  9. }
  10. }
  11. }

1.1.4 【必须】ClassNotFoundException 异常捕获

同 1.1.3

1.2 数据泄露

1.2.1 【必须】logcat 输出限制

release 版本禁止在 logcat 输出信息。

  1. public class MainActivity extends Activity {
  2. String DEBUG = "debug_version";
  3. protected void onCreate(Bundle savedInstanceState) {
  4. // ......
  5. if (DEBUG == "debug_version") {
  6. Log.d("writelog", "start activity");
  7. }
  8. // ......
  9. }
  10. }

1.3 webview 组件安全

1.3.1 【必须】addJavaScriptInterface 方法调用

对于设置 minsdk <= 18 的应用,禁止调用 addJavaScriptInterface 方法。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. mWebView = new WebView(this);
  5. if (Build.VERSION.SDK_INT > 18) {
  6. mWebView.addJavascriptInterface(new wPayActivity.InJavaScriptLocalObj(this), "local_obj");
  7. }
  8. // ......
  9. }
  10. }

1.3.2 【建议】setJavaScriptEnabled 方法调用

如非必要,setJavaScriptEnabled 应设置为 false 。加载本地 html ,应校验 html 页面完整性,以避免 xss 攻击。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. mWebView = new WebView(this);
  5. mWebView.getSettings().setJavaScriptEnabled(false);
  6. // ......
  7. }
  8. }

1.3.3 【建议】setAllowFileAccess 方法调用

建议禁止使用 File 域协议,以避免过滤不当导致敏感信息泄露。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. mWebView = new WebView(this);
  5. mWebView.getSettings().setAllowFileAccess(false);
  6. // ......
  7. }
  8. }

1.3.4 【建议】setSavePassword 方法调用

建议 setSavePassword 的设置为 false ,避免明文保存网站密码。 建议禁止使用 File 域协议,以避免过滤不当导致敏感信息泄露。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. mWebView = new WebView(this);
  5. mWebView.getSettings().setSavePassword(false);
  6. // ......
  7. }
  8. }

1.3.5 【必须】onReceivedSslError 方法调用

webview 组件加载网页发生证书认证错误时,不能直接调用 handler.proceed() 忽略错误,应当处理当前场景是否符合业务预期,以避免中间人攻击劫持。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. mWebView = new WebView(this);
  5. mWebView.setWebViewClient(new WebViewClient() {
  6. @Override
  7. public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  8. // must check error
  9. check_error();
  10. handler.proceed();
  11. }
  12. }
  13. // ......
  14. }
  15. }

1.4 传输安全

1.4.1 【必须】自定义 HostnameVerifier 类

自定义 HostnameVerifier 类后,必须实现 verify 方法校验域名,以避免中间人攻击劫持。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. HostnameVerifier hnv = new HostnameVerifier() {
  5. @Override
  6. public boolean verify(String hostname, SSLSession session) {
  7. // must to do
  8. isValid = checkHostName(hostname);
  9. return isValid;
  10. }
  11. };
  12. // ......
  13. }
  14. }

1.4.2 【必须】自定义 X509TrustManager 类

自定义 X509TrustManager 类后,必须实现 checkServerTrusted 方法校验服务器证书,以避免中间人攻击劫持。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. TrustManager tm = new X509TrustManager() {
  5. public void checkServerTrusted(X509Certificate[] chain, String authType)
  6. throws CertificateException {
  7. // must to do
  8. check_server_valid();
  9. }
  10. };
  11. // ......
  12. }
  13. }

1.4.3 【必须】setHostnameVerifier 方法调用

禁止调用 setHostnameVerifier 方法设置 ALLOW_ALL_HOSTNAME_VERIFIER 属性,以避免中间人攻击劫持。

  1. public class MainActivity extends Activity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. // ......
  4. SchemeRegistry schemeregistry = new SchemeRegistry();
  5. SSLSocketFactory sslsocketfactory = SSLSocketFactory.getSocketFactory();
  6. // set STRICT_HOSTNAME_VERIFIER
  7. sslsocketfactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
  8. // ......
  9. }
  10. }