Android编程规范摘要7 (安全)

安全


其它相关文章:
Android编程规范摘要1 (资源文件命名与使用)
Android编程规范摘要2 (基本组件)
Android编程规范摘要3 (UI与布局)
Android编程规范摘要4 (进程、线程与消息通信)
Android编程规范摘要5 (文件与数据库)
Android编程规范摘要6 (Bitmap、Drawable 与动画)
Android编程规范摘要7 (安全)


  1. [强制] 禁止使用常量初始化矢量参数构建IvParameterSpec,建议IV通过随机方式产生。

    • 说明: 使用常量初始化向量,密码文本的可预测性会高得多,容易受到字典式攻击。iv 的作用主要是用于产生密文的第一个block,以使最终生成的密文产生差异(明文相同的情况下),使密码攻击变得更为困难。
    • 正例:

      byte[] rand = new byte[16];
      SecureRandom r = new SecureRandom();
      r.nextBytes(rand);
      IvParameterSpec iv = new IvParameterSpec(rand);
    • 反例:

      IvParameterSpec iv_ = new IvParameterSpec("1234567890".getBytes());
      System.out.println(iv.getIV());
  2. [强制] 将android:allowbackup 属性必须设置为false,阻止应用数据被导出。

    • 说明:android:allowBackup 原本是 Android 提供的 adb 调试功能,如果设置为 true,可以导出应用数据备份并在任意设备上恢复。这对应用安全性和用户数据隐私构成
      极大威胁,所以必须设置为 false,防止数据泄露。
    • 正例:

      <application
          android:allowBackup="false"
          android:largeHeap="true"
          android:icon="@drawable/test_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" >
  3. [强制] 如果使用自定义HostnameVerifier 实现类,必须在verify()方法中校验服务器主机名的合法性,否则可能受到中间人攻击。

    • 说明:在与服务器建立 https 连接时,如果 URL 的主机名和服务器的主机名不匹配,则可通过该回调接口来判断是否应该允许建立连接。如果回调内实现不恰当,没有有效校验主机名,甚至默认接受所有主机名,会大大增加安全风险。
    • 反例:

      HostnameVerifier hnv = new HostnameVerifier() {
          @Override
          public boolean verify(String hostname, SSLSession session) {
          // 不做校验,接受任意域名服务器
              return true;
          }
      };
      HttpsURLConnection.setDefaultHostnameVerifier(hnv);
  4. [强制] 如果使用自定义X509TrustManager 实现类,必须在checkServerTrusted() 方法中校验服务端证书的合法性,否则可能受到中间人攻击。

    • 说明: 常见误区是checkServerTrusted()方法根本没有实现,这将导致 X509TrustManager 形同虚设。该方法中需要实现完备的校验逻辑,对于证书错误抛出CertificateException
    • 正例:

      HostnameVerifier hnv = new HostnameVerifier() {
          @Override
          public boolean verify(String hostname, SSLSession session) {
              if("yourhostname".equals(hostname)){
                  return true;
              } else {
                  HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
              return hv.verify(hostname, session);
              }
          }
      };
    • 反例:

      TrustManager tm = new X509TrustManager() {
          public void checkClientTrusted(X509Certificate[] chain, String authType)
              throws CertificateException {
              //do nothing,接受任意客户端证书
          }
          public void checkServerTrusted(X509Certificate[] chain, String authType)
              throws CertificateException {
              //do nothing,接受任意服务端证书
          }
          public X509Certificate[] getAcceptedIssuers() {
              return null;
          }
      };
      sslContext.init(null, new TrustManager[] { tm }, null);
  5. [强制] 在SDK 支持的情况下,Android 应用必须使用V2 签名,这将对APK 文件的修改做更多的保护。

  6. [强制] 所有的 Android 基本组件(Activity、Service、BroadcastReceiver、ContentProvider 等)都不应在没有严格权限控制的情况下,将 android:exported 设置为 true。

  7. [强制] WebView 应设置下列属性,阻止file scheme URL 的访问。

    • WebView#getSettings()#setAllowFileAccess(false)
    • WebView#getSettings()#setAllowFileAccessFromFileURLs(false)
    • WebView#getSettings()#setAllowUniversalAccessFromFileURLs(false)
  8. [强制] 不要把敏感信息打印到log 中。

  9. [强制] 确保应用发布版本的android:debuggable 属性设置为false。

  10. [强制] 本地加密秘钥不能硬编码在代码中,更不能使用 SharedPreferences 等本
    地持久化机制存储。应选择Android 自身的秘钥库(KeyStore)机制或者其他安全
    性更高的安全解决方案保存。

  11. [建议] addJavascriptInterface()可以添加JS对本地Java方法的调用, 但这本身会导致恶意代码的攻击。 在Android 4.2(API Level 17)以下,不应再使用这样的调用方式。在Android 4.2 及以上,需要对本地被远程调用的方法显式添加@JavascriptInterface annotation

  12. [强制] 使用Android的AES/DES/DESede加密算法时,不要使用ECB加密模式,应使用CBC或CFB加密模式。

    • 说明: 加密模式有 ECB、CBC、CFB、OFB 等,其中 ECB 的安全性较弱,如果使用固定的密钥,相同的明文将会生成相同的密文,容易受到字典攻击。
    • 建议: 使用 CBC、CFB 或OFB 等模式。
    • 加密方式说明:
      • ECB:Electronic codebook,电子密码本模式
      • CBC:Cipher-block chaining,密码分组链接模式
      • CFB:Cipher feedback,密文反馈模式
      • OFB:Output feedback,输出反馈模式
  13. [强制] Android APP 在HTTPS 通信中,验证策略需要改成严格模式。

    • 说明: Android APP 在HTTPS通信中,使用ALLOW_ALL_HOSTNAME_VERIFIER,表示允许和所有的HOST 建立SSL 通信,这会存在中间人攻击的风险,最终导致敏感信息可能会被劫持,以及其他形式的攻击。
    • 反例:

      //使用了ALLOW_ALL_HOSTNAME_VERIFIER, 应改成STRICT_HOSTNAME_VERIFIER。
      SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
      sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    • ALLOW_ALL_HOSTNAME_VERIFIER : 关闭host 验证,允许和所有的host 建立SSL 通信,
    • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER: 和浏览器兼容的验证策略,即通配符能够匹配所有子域名。
    • STRICT_HOSTNAME_VERIFIER : 严格匹配模式,hostname 必须匹配第一个CN 或者任何一个subject-alts
  14. 在Android 4.2(API Level 17)及以上,对安全性要求较高的应用可在Activity中,对 Activity 所关联的 Window 应用 WindowManager.LayoutParams.FLAG_SECURE,防止被截屏、录屏。但要注意的是,一个 Activity 关联的Window可能不止一个,如果使用了Dialog/DialogFragment等控件弹出对话框,它们本身也会创建一个新的 Window,也一样需要保护。

  15. zip 中不要包含 ../../file 这样的路径,可能被篡改目录结构,造成攻击。

    • 说明: 当zip 压缩包中允许存在”../”的字符串,攻击者可以利用多个”../”在解压时改变zip 文件存放的位置,当文件已经存在是就会进行覆盖,如果覆盖掉的文件是so、dex 或者odex 文件,就有可能造成严重的安全问题。
    • 正例: 对路径进行判断,存在”..”时抛出异常。

      //对重要的Zip 压缩包文件进行数字签名校验,校验通过才进行解压
      String entryName = entry.getName();
      if (entryName.contains("..")){
      throw new Exception("unsecurity zipfile!");
      }
    • 反例:

      BufferedOutputStream dest = null;
      try {
          ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream("/Users/yunmogong/Documents/test/test.zip")));
          ZipEntry entry;
          while ((entry = zis.getNextEntry()) != null){
              int count;
              byte data[] = new byte[BUFFER];
              String entryName = entry.getName();
              FileOutputStream fos = new FileOutputStream(entryName);
              //System.out.println("Extracting:" + entry);
              dest = new BufferedOutputStream(fos, BUFFER);
              while ((count=zis.read(data,0,BUFFER)) != -1){
                  dest.write(data, 0, count);
              }
              dest.flush();
          }
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          try {
              dest.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  16. [强制] MD5 和SHA-1、SHA-256 等常用算法是Hash 算法,有一定的安全性,但不能代替加密算法。敏感信息的存储和传输,需要使用专业的加密机制。

  17. [强制] 不能使用System.out.println 打印log。

  18. [强制] Log 的tag 不能是” “。
    • 日志的tag 是空字符串没有任何意义,也不利于过滤日志。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值