java应用程序开发
安全性是软件开发中最复杂,最广泛和最重要的方面之一。 在开发周期结束时,软件安全性也经常被忽略,或者被简化为仅需进行少量调整。 我们可以在年度主要数据安全漏洞清单中看到结果,该清单在2019年总计超过30亿条暴露记录。 如果Capital One可能发生这种情况,那么您也可能发生这种情况。
好消息是Java是具有许多内置安全性功能的长期开发平台。 Java安全性软件包已经过严格的测试,并且经常针对新的安全漏洞进行更新。 2017年9月发布的更新的Java EE安全API解决了云和微服务架构中的漏洞。 Java生态系统还包括用于分析和报告安全性问题的各种工具。
但是,即使有了可靠的开发平台,也要保持警惕。 应用程序开发是一项复杂的工作,漏洞可能隐藏在背景噪声中。 您应该在应用程序开发的每个阶段都考虑安全性,从类级别的语言功能到API端点授权。
以下基本规则为构建更安全的Java应用程序奠定了良好的基础。
Java安全性规则#1:编写干净而强大的Java代码
漏洞喜欢隐藏在复杂性中,因此请在不牺牲功能的情况下使代码尽可能简单。 使用经过验证的设计原则(例如DRY)(不要重复),将帮助您编写更易于查看问题的代码。
始终在代码中公开尽可能少的信息。 隐藏实施细节支持可维护和安全的代码。 这三个技巧将大大有助于编写安全的Java代码:
- 充分利用Java的访问修饰符
- 避免反思和内省 。 在某些情况下,应该使用这种高级技术,但是在大多数情况下,您应该避免使用它们。 使用反射消除了强类型化,强类型化可能会给代码引入弱点和不稳定性 。 将类名与字符串进行比较容易出错,并且很容易导致名称空间冲突。
- 始终定义尽可能小的API和接口表面 。 解耦组件并使它们在尽可能小的区域内交互。 即使您的应用程序的某个区域感染了漏洞,其他区域也将是安全的。
Java安全性规则2:避免序列化
这是另一个编码技巧,但重要的是要成为一个规则。 序列化接受远程输入,并将其转换为完全赋值的对象。 它省去了构造函数和访问修饰符,并允许未知数据流成为JVM中的运行代码。 结果,Java序列化从根本上来说是不安全的。
Java序列化的结尾
如果您没有听说过,Oracle就有长期计划从Java中删除序列化 。 Oracle公司Java平台小组的首席架构师Mark Reinhold说,他相信所有Java漏洞中的三分之一或更多都涉及序列化 。
尽可能避免在Java代码中进行序列化/反序列化。 相反,请考虑使用JSON或YAML之类的序列化格式 。 永远不要公开接收并作用于序列化流的不受保护的网络端点。 这不过是混乱的欢迎垫。
Java安全规则#3:永远不要公开未加密的凭证或PII
很难相信,但是这种可避免的错误会导致年复一年的痛苦。
当用户在浏览器中输入密码时,密码将以纯文本格式发送到您的服务器。 那应该是它最后一次见面。 您必须先通过单向密码对密码进行加密,然后再将其持久保存到数据库中,然后在每次与该值进行比较时再次进行加密。
密码规则适用于所有个人身份信息(PII):信用卡,社会保险号等。委托给您应用程序的任何个人信息都应得到最高程度的保护。
数据库中未加密的凭据或PII是一个巨大的安全漏洞,正在等待攻击者发现。 同样,切勿将原始凭据写入日志,或以其他方式传输到文件或网络。 而是为您的password创建一个盐腌哈希 。 确保进行研究并使用推荐的哈希算法 。
跳至规则4:始终使用库进行加密; 不要自己动手。
Java安全规则4:使用已知和经过测试的库
全神贯注于有关滚动自己的安全算法的问答 。 tl; dr课程是:尽可能使用已知的可靠库和框架。 从密码哈希到REST API授权,这适用于整个范围。
幸运的是,Java及其生态系统支持您。 对于应用程序安全性, Spring Security是事实上的标准。 它提供了广泛的选择和灵活性,以适应任何应用程序体系结构,并且融合了多种安全方法。
解决安全性的第一个本能应该是进行研究。 研究最佳实践,然后研究哪个图书馆将为您实施这些实践。 例如,如果您要使用JSON Web令牌来管理身份验证和授权,请查看封装JWT的Java库,然后学习如何将其集成到Spring Security中。
即使使用可靠的工具,也很容易捆绑授权和身份验证。 确保缓慢移动并仔细检查您所做的一切。
Java安全性规则5:对外部输入抱有幻想
无论是来自用户输入表单,数据存储区还是远程API,都不要信任外部输入。
SQL注入和跨站点脚本(XSS)只是由于处理外部输入错误而引起的最常见攻击。 一个鲜为人知的示例(其中很多示例)是“ 十亿笑声攻击 ”,通过这种攻击 ,XML实体扩展会导致拒绝服务攻击。
每当您收到输入时,都应该对其进行完整性检查和消毒。 对于可能呈现给另一个工具或系统进行处理的任何事物,尤其如此。 例如,如果某些事情可能会成为OS命令行的参数,请当心:
一个特殊的众所周知的实例是SQL注入,它将在下一条规则中介绍。
Java安全规则#6:始终使用准备好的语句来处理SQL参数
每当您构建一条SQL语句时,您都有可能插值一段可执行代码。
知道这一点后, 始终 使用java.sql.PreparedStatement类创建SQL是一个好习惯。 对于NoSQL存储(如MongoDB)也存在类似的功能。 如果您使用的是ORM层,则实现将在后台使用PreparedStatement 。
Java安全规则7:不要通过错误消息来揭示实现
生产中的错误消息可以为攻击者提供丰富的信息来源。 堆栈跟踪尤其可以揭示有关您正在使用的技术及其使用方式的信息。 避免向最终用户显示堆栈跟踪。
登录失败警报也属于此类别。 通常接受的错误消息应为“登录失败”与“未找到该用户”或“密码不正确”。 为潜在的恶意用户提供尽可能少的帮助。
理想情况下,错误消息不应泄露您应用程序的基础技术堆栈。 使该信息尽可能不透明。
Java安全性规则#8:使安全性发布保持最新
截至2019年,Oracle 对Java实施了新的许可方案和发布时间表 。 不幸的是,对于开发人员而言,新的发布节奏并没有使事情变得更容易。 但是,您仍然需要经常检查安全更新并将其应用到JRE和JDK。
通过定期检查Oracle主页以获取安全警报,确保知道可用的重要补丁程序。 每个季度,Oracle都会为Java的当前LTS(长期支持)版本提供一个自动补丁更新。 问题是,只有在您购买Java支持许可证的情况下,该补丁才可用。
如果您的组织正在为此类许可证付费,请遵循自动更新路线。 如果没有,您可能正在使用OpenJDK,则必须自己进行修补。 在这种情况下,您可以应用二进制补丁,也可以简单地用最新版本替换现有的OpenJDK安装。 或者,您可以使用商业支持的OpenJDK,例如Azul的Zulu Enterprise 。
您是否需要每个安全补丁?
如果您密切关注安全警报,可能会发现您不需要给定的一组更新。 例如,2020年1月的发行版似乎是Java的重要更新。 但是,仔细阅读后发现,此更新仅修补了Java applet安全性方面的漏洞,并不影响Java服务器。
Java安全规则#9:查找依赖项漏洞
有许多工具可以自动扫描您的代码库和依赖项是否存在漏洞。 您所要做的就是使用它们。
OWASP(开放式Web应用程序安全性项目)是致力于改善代码安全性的组织。 OWASP的值得信赖的高质量自动代码扫描工具列表包括多个面向Java的工具。
定期检查您的代码库,但还要注意第三方依赖性。 攻击者同时针对开放源代码库和封闭源代码库。 监视对依赖项的更新,并在发布新的安全修复程序时更新系统。
Java安全规则#10:监视和记录用户活动
如果您没有积极地监视应用程序,那么即使是简单的暴力攻击也可能成功。 使用监视和日志记录工具来监视应用程序的运行状况。
如果您想确信监视为何如此重要,只需坐在并在应用程序侦听端口上观看TCP数据包即可。 除了简单的用户交互之外,您还将看到各种活动。 其中一些活动将是机器人和邪恶者扫描漏洞。
您应该记录和监视失败的登录尝试,并部署对策以防止远程客户端不受攻击地受到攻击。
监视可以提醒您注意无法解释的峰值,而日志记录可以帮助您了解攻击后出了什么问题。 Java生态系统包括大量用于日志记录和监视的商业和开源解决方案。
Java安全规则#11:当心拒绝服务(DoS)攻击
每当您处理潜在的昂贵资源或进行潜在的昂贵操作时,都应防止资源使用失控。
Oracle在其“ Java SE安全编码指南”文档的“拒绝服务”标题下维护了针对此类问题的潜在媒介列表。
基本上,每当您要执行昂贵的操作(例如将压缩文件解压缩)时,都应该监视资源使用量爆炸式增长。 不信任文件清单。 仅信任实际的磁盘或内存消耗,对其进行监视,并防止服务器过度使用。
同样,在某些处理中,务必注意意外的永久循环。 如果怀疑存在环路,请添加一个保护措施以确保该环路正在进展中,并在环路看起来像僵尸时将其短路。
Java安全规则#12:考虑使用Java安全管理器
Java有一个安全管理器 ,可用于限制正在运行的进程可以访问的资源。 它可以根据磁盘,内存,网络和JVM访问来隔离程序。 缩小对应用程序的这些要求,可以减少攻击可能造成的危害。 这种隔离也可能带来不便,这就是为什么默认情况下不启用SecurityManager原因。
您必须自己决定围绕SecurityManager的强硬见解是否值得为您的应用程序提供额外的保护。 请参阅Oracle文档,以了解有关Java安全管理器的语法和功能的更多信息 。
Java安全规则#13:考虑使用外部云身份验证服务
某些应用程序仅必须拥有其用户数据。 其余的,云服务提供商可能有意义。
到处搜索,您会发现一系列的云身份验证提供程序。 这种服务的好处在于,提供者负责保护敏感的用户数据,而不是您。 另一方面,添加身份验证服务会增加企业体系结构的复杂性。 一些解决方案(例如FireBase Authentication )包括用于在整个堆栈中集成的SDK。
结论
我提出了13条规则来开发更安全的Java应用程序。 这些规则是反复试验的,但最大的规则是:多疑。 始终以谨慎和安全意识来进行软件开发。 在代码中查找漏洞,利用Java安全API和软件包,并使用第三方工具监视和记录代码中的安全问题。
以下是三个很好的高级资源,它们可以与不断变化的Java安全形势保持同步:
- OWASP前十名
- CWE前25名
- Oracle的安全代码准则
JavaWorld发布的
翻译自: https://www.infoworld.com/article/2076837/twelve-rules-for-developing-more-secure-java-code.html
java应用程序开发