【Java核心-安全基础】编写安全的Java代码

实现安全的Java代码,需要从功能设计到实现细节,都充分考虑可能的安全影响。

以消耗系统资源为目的的攻击是很常见的方式。

CPU、线程、内存、文件描述符、数据库连接、再入锁等各种资源都可能成为攻击者消耗的目标。

常见代码问题

数值运算溢出

如:

Java代码

 

  1. if (a+b<c) {  

  2.   ...  

  3. }  

a+b 可能超出上限。改成 a<c-b 也有溢出的风险。

需要根据各变量的范围进行处理。

异常中包含敏感信息

如:

Java代码

 

  1. try {  

  2.   ...  

  3. } catch (Exception e) {  

  4.   throw new RuntimeException(hostname + port + " not available");  

  5. }  

如果异常中包含了敏感信息,最终又未最好脱敏处理,就存在信息安全风险。

如果没有明确的必要性,一般不建议输出这些内部的敏感信息。

如,华为的“安全红线”就不允许日志中存在文件名等信息。

在一些安全标准特别高的系统中,敏感信息被使用后,需立即明确在内存中销毁,以免被探测或在core dump时意外暴露。

如,在使用密码的场景中,可以用 char[] 来临时存放密码,而不是String。

使用完后,用随机字符覆盖char[]。这样可以避免因String的不可变性,导致密码一直留在堆,直到被垃圾回收。

序列化安全

Java序列化也是安全问题频发的场景。

通常建议:

  • 敏感信息不要被序列化。可以用transient关键字防止相关字段被序列化。

  • 反序列化时,在readObject中实现与对象构建过程相同的安全检查和数据校验。

JDK 9 中还可以通过 ObjectInputFilter 来限定允许被序列化的类型(黑白名单)。

工程实践

代码安全问题细节繁杂,全凭人肉记忆很不现实。

在实际工程中,需借助工具和流程管控等综合处理。

可根据实际情况选择合适的方案,平衡安全与迭代节奏。

开发测试阶段

一些典型的做法:

  • 早期设计阶段,由安全专家组对新特性进行风险评估。

    很多组织并没有这个能力/资源做风险评估。

    甚至关键决策人根本不具备这方面意识和能力。

    全靠一线资深员工尽心尽责。

    这种能力配不上职位的领导管理是非常危险的。

  • 在开发过程及code review阶段,应用代码规范和相关工具进行检查。

    《阿里巴巴Java开发手册》及相关配套工具就是常见工具之一。

  • 利用多种静态分析工具,如 FindBugs,检查潜在的安全风险。

  • JDK的警告也需要当作错误认真处理。

  • 在代码提交入库等关键环节,利用hook机制调用检查工具,阻止不合规的代码入库。

静态分析工具并不需要大而全,“足够好”就行。没有工具能发现所有问题。

在保证功能的前提下,需考虑降低分析过程的噪音信息,提高分析效率。

部署阶段

JDK自身缺陷的处理可以算部署阶段的安全事务。

关注JDK更新的安全漏洞补丁并及时更新是安全管理的一部分。

对安全敏感的产品,还需关注JDK在加解密方面的路线图。

Oracle JRE and JDK Cryptographic Roadmap

发布了219 篇原创文章 · 获赞 3 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/hchaoh/article/details/103906514