(SAST检测规则-8)连接字符串中的硬编码密码

严重等级:高危

缺陷详解:

在构建数据驱动的应用程序时,开发者通常需要通过数据库连接字符串与数据库进行交互。将敏感信息(如密码、服务器IP地址或加密密钥)硬编码在源代码中会带来以下风险:

  1. 信息暴露:硬编码的密码、IP地址或密钥可能被反编译工具提取,从而被攻击者利用。
  2. 代码维护困难:调试和生产环境的配置不同,每次环境切换都需要手动修改代码和重新编译,增加维护成本。
  3. 法律后果:敏感信息的泄露可能违反行业法规,如 ITAR(国际武器贸易条例)或 HIPAA(健康保险流通与责任法案),引发法律责任。
  4. 易受攻击:如果恶意用户获得了源代码或类文件,他们可以直接读取硬编码的信息,绕过其他安全机制。

导致结果和风险:

  1. 硬编码的敏感信息容易被攻击者利用,导致数据泄露或未经授权的访问。
  2. 敏感数据泄露可能影响企业的合规性,带来法律和声誉风险。

缓解和预防措施:

  1. 配置外部化:将数据库连接信息从代码中分离出来,存储在加密的配置文件、环境变量或专用的密钥管理系统中。
  2. 加密存储:敏感信息应加密存储,并在运行时通过安全机制解密。
  3. 访问控制:确保敏感配置文件或密钥管理系统的访问权限受到严格控制。
  4. 最小权限原则:数据库账户应设置为只具有最低限度的操作权限,避免因密码泄露导致更大范围的风险。

测试用例

修复前的测试用例(存在漏洞):

import java.sql.Connection;

import java.sql.DriverManager;

public class HardcodedPasswordExample {

    public static void main(String[] args) {

        try {

            // 在代码中硬编码数据库连接字符串,包括用户名和密码

            String url = "jdbc:mysql://prod.company.com/production";

            String username = "root";

            String password = "lamepassword"; // 硬编码的密码

            // 使用硬编码信息连接数据库

            Connection connection = DriverManager.getConnection(url, username, password);

            System.out.println("数据库连接成功!");

        } catch (Exception e) {

            System.out.println("数据库连接失败!");

            e.printStackTrace();

        }

    }

}

漏洞分析:

  • 问题:数据库连接的敏感信息直接硬编码在程序中,易被反编译工具提取。
  • 风险:攻击者可通过代码或编译文件直接获取敏感信息,访问数据库。

修复后的测试用例(安全实现):

import java.sql.Connection;

import java.sql.DriverManager;

import java.util.Properties;

import java.nio.file.Files;

import java.nio.file.Paths;

public class SecurePasswordExample {

    public static void main(String[] args) {

        try {

            // 从外部配置文件加载数据库连接信息

            Properties props = new Properties();

            props.load(Files.newInputStream(Paths.get("config.properties")));

            // 从配置文件中读取连接字符串、用户名和密码

            String url = props.getProperty("db.url");

            String username = props.getProperty("db.username");

            String password = props.getProperty("db.password");

            // 使用安全加载的配置信息连接数据库

            Connection connection = DriverManager.getConnection(url, username, password);

            System.out.println("数据库连接成功!");

        } catch (Exception e) {

            System.out.println("数据库连接失败!");

            e.printStackTrace();

        }

    }

}

修复点:

  • 将敏感信息存储在 外部加密配置文件(如 config.properties)中,而非硬编码。
  • 配置文件的访问权限受到严格控制,防止未授权访问。

示例配置文件(config.properties):

db.url=jdbc:mysql://prod.company.com/production

db.username=root

db.password=securepassword123


补充测试用例:

1. 使用环境变量存储密码:

public class EnvVariableExample {

    public static void main(String[] args) {

        try {

            // 从环境变量中加载敏感信息

            String url = System.getenv("DB_URL");

            String username = System.getenv("DB_USERNAME");

            String password = System.getenv("DB_PASSWORD");

            // 使用环境变量连接数据库

            Connection connection = DriverManager.getConnection(url, username, password);

            System.out.println("数据库连接成功!");

        } catch (Exception e) {

            System.out.println("数据库连接失败!");

            e.printStackTrace();

        }

    }

}

2. 使用密钥管理系统:

public class SecureKeyManagementExample {

    public static void main(String[] args) {

        try {

            // 从密钥管理系统加载敏感信息

            String url = SecretManager.get("db.url");

            String username = SecretManager.get("db.username");

            String password = SecretManager.get("db.password");

            // 使用密钥管理系统的值连接数据库

            Connection connection = DriverManager.getConnection(url, username, password);

            System.out.println("数据库连接成功!");

        } catch (Exception e) {

            System.out.println("数据库连接失败!");

            e.printStackTrace();

        }

    }

}

漏洞修复后的优势:

  • 密钥管理系统和环境变量保护了敏感信息,降低被暴露的风险。
  • 数据库连接信息的动态管理提升了代码可维护性。

参考:

工作:SAST工具推介、评测、代码审计、培训资料、应用安全咨询、SAST检测规则、安全漏洞数据处理、许可证数据处理、组件数据处理等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

manok

你的打赏很重要

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值