1、硬编码密码
硬编码密码是指在程序中采用硬编码方式处理密码。这种处理方式一方面不易于程序维护,在代码投入使用后,除非对软件进行修补,否则无法修改密码。另一方面会削弱系统安全性,硬编码密码意味着拥有代码权限的人都可以查看到密码,可以使用密码访问一些不具有权限的系统,更严重的是如果攻击者能够访问应用程序的字节码,利用一些反编译工具就能阅读到代码,可以轻易获得密码。
本文以JAVA语言源代码为例,分析硬编码密码缺陷产生的原因及修复方法。详见 CWE ID 259: Use of Hard-coded Password (http://cwe.mitre.org/data/definitions/259.html)。
2、 硬编码密码的危害
硬编码密码漏洞一旦被利用,造成的安全问题一般无法被轻易修正。例如:在代码中泄露利用未指定账户的硬编码密码,这样远程攻击者获取到敏感信息,可以通过访问数据库获得管理控制权限;本地用户可以通过读取配置文件中的硬编码用户名和密码来执行任意代码。
从2018年1月至2019年3月,CVE中共有29条漏洞信息与其相关。部分漏洞如下:
CVE | 概述 |
---|---|
CVE-2019-6499 | Teradata Viewpoint 14.0 和16.20.00.02-b80 在视点数据库帐户 (perspective-portal conf server.xml) 中使用硬编码密码,恶意用户可能利用该密码来破坏系统。 |
CVE-2018-18006 | 用于 Windows 的 Ricoh myPrint 应用程序 2.9.2.4 和用于 Android 的 2.2.7 的硬编码密码可以访问任何外部公开的 myPrint WSDL API,如通过发现相关Google云打印机的 API 机密,邮件服务器的加密密码和打印的名称所证明的文件。 |
CVE-2018-6387 | iBall iB-WRA150N 1.2.6 build 110401 Rel.47776n 设备具有管理员帐户的硬编码密码,以及用普通账户硬编码密码。 |
CVE-2018-5726 | MASTER IPCAMERA01 3.3.4.2103 设备允许远程攻击者通过精心设计的 HTTP 请求获取敏感信息,如用户名,密码和配置设置所示。 |
3、示例代码
示例源于Samate Juliet Test Suite for Java v1.3 (https://samate.nist.gov/SARD/testsuite.php),源文件名:CWE259_Hard_Coded_Password__driverManager_01java。
3.1缺陷代码
上述示例代码是一个连接数据库执行 SQL 语句的操作。在第33行中,给数据库连接的密码赋值。在第44行使用该密码进行数据库连接,第45-46行执行了 sql 语句。这仅仅是一个简单的数据库操作,在第33行对数据库连接的密码进行硬编码,这种处理方式不易于维护且会削弱系统安全性。
使用360代码卫士对上述示例代码进行检测,可以检出“硬编码密码”缺陷,显示等级为中。从跟踪路径中可以分析出数据的污染源以及数据流向,在代码行第44行报出缺陷,如图1所示:
图1:硬编码密码的检测示例
3.2 修复代码
在上述修复代码中,首先将数据库连接的用户名密码先加密放入 db.properties 文件中。
在第95行,封装一个获取配置文件中用户名密码并解密的方法。在第98行用流读入properties 配置文件,在第101行从输入字节流读取属性列表(键和元素对),在第102行用此属性列表中指定的键搜索属性,获取用户名或密码的加密值,在第104行调用封装的解密方法,将配置文件中已加密的用户名和密码解密。
此时,在第45-46调用封装的 getProperties()方法行从配置文件中读取加密的用户名和密码。这样提高了系统安全性,也便于系统维护,当在生产环境中需要修改密码时,并不需要对程序进行修补,直接修改配置文件即可。使用360代码卫士对修复后的代码进行检测,可以看到已不存在“硬编码密码”缺陷。如图2:
图2:修复后检测结果
4 、如何避免硬编码密码
通常情况下,应对密码加以模糊化,并且在外部资源文件中进行处理。
在系统中采用明文的形式存储密码,会造成任何有充分权限的人读取和无意中误用密码。至少,密码要先经过hash处理再存储。