jdbc
连接数据库
1 |
|
这个就是完整的连接数据库的逻辑
现在就有一个问题了
为什么需要Class.forName 提前注册?
需要了解Class.forName 的作用:动态加载类到 JVM 中并执行类的初始化
那为什么需要呢?
1 |
|
可以通过这个类发现,需要通过反射,registerDriver
但是为什么在删除这个之后有时候发现也能正常的执行数据库连接?
那就又要掏出另一个概念了-SPI
深入理解 Java 中 SPI 机制 - 知乎 (zhihu.com)
简单的说就是会主动的找classpath 对应的目录下的META-INF/services 并将这个包中的内容加载到jvm 中
这一步就是完全自动化的
在jdbc 中
这个类就会自动的加载
问题思考
SPI机制
是否有安全性问题?- SPI通过扫描
META-INF/services
目录下的配置文件动态加载实现类,攻击者可能篡改配置文件或植入恶意JAR包,导致加载未经验证的类并执行恶意代码。例如,若服务提供者的实现类中包含反射调用危险方法(如Runtime.exec()),可能直接触发远程代码执行(RCE) - Java默认的类加载机制未严格限制SPI实现类的来源。若未配合安全管理器(
SecurityManager
)或沙箱类加载器,攻击者可利用SPI加载来自不可信路径的类,突破权限隔离 - SPI的配置文件以明文形式存储于JAR包中,攻击者可通过修改
META-INF/services
下的接口文件内容,指定恶意实现类路径,从而劫持服务加载过程
- SPI通过扫描
Java反射
有那些安全问题?- 默认加载的时候可能存在恶意的static 代码,以至于不需要实例化对象,就在默认调用的时候完成了攻击
- 反射允许直接访问和修改类的私有字段、方法或构造器,例如通过setAccessible(true)绕过private修饰符的限制。这可能导致敏感数据泄露(如密码字段)或破坏对象封装性。
- 反射常与反序列化结合使用,若反序列化数据不可信,可能触发恶意代码执行(如通过ObjectInputStream加载恶意对象)
Java类加载机制
是什么?就是将class 文件加载到jvm 中的机制。这个机制中最出名的模型是双亲委派模型。就是子加载在加载的时候不会先加载,而是向上抛给上一层加载器。一直到顶层的加载器无法加载,才会逐步向下尝试加载。
一些风险:
- 如果攻击者能够控制应用程序使用的类加载器,或者能够注入一个恶意的自定义类加载器,他们就可以加载任意的恶意代码。
- 虽然自定义类加载器通常建议重写
findClass()
以遵循双亲委派,但如果错误地重写了loadClass()
并破坏了委派链,可能会导致命名空间混淆或加载非预期的类版本。 java.lang.ClassLoader
的protected final byte[] defineClass(String name, byte[] b, int off, int len)
方法可以将一个字节数组转换为Class
对象。如果攻击者能够控制传递给此方法的字节数组内容,他们就可以在JVM中定义任意类。java.net.URLClassLoader
可以从指定的URL加载类和资源。如果URL来源不受信任或可被攻击者控制,那么JVM就会加载并可能执行恶意代码。- 类加载器不仅加载类,还加载资源(如配置文件、图片等)通过
getResource()
或getResourceAsStream()
。如果自定义类加载器在构造资源路径时未对输入进行充分验证,可能导致路径操纵,读取到非预期的本地文件或发起非预期的网络请求(类似SSRF,如果从URL加载资源)。
数据库连接时密码安全问题?
使用JDBC如何写一个通用的
数据库密码爆破
模块?
jdbc
https://tsy244.github.io/2025/05/17/java安全/jdbc/