java-sec-code中的sql注入

java-sec-code
用于学习java漏洞代码
环境部署
直接在idea中git 运行即可

sql注入

环境中主要是两个 分别为jdbc和mybatis

jdbc
  1. 存在问题的写法

直接获取用户传入的数据,拼接执行

String sql = "select * from users where username = '"
 + request.getParameter(username)+ "'";
ResultSet rs = statement.executeQuery(sql);

由于这里没有回显,使用延时注入方式进行验证,

http://127.0.0.1:8080/sqli/jdbc/vuln?username=joychou' and if(ascii(substr(database(),1,1))= 106,sleep(5),0) -- +
  1. 预编译写法
username=request.getParameter("username");  
String sql = "select * from users where username = ?";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, username);

使用 ? 作为占位符,然后使用 setInt() 方法设置参数的值
PreparedStatement 接口会将输入的数据进行转义,例如

joychou变为'joychou'
joychou'变为'joychou\''

防御sql注入问题

mybatis

1,存在漏洞的写法

@Select("select * from users where username = '${username}'")
List<User> findByUserNameVuln01(@Param("username") String username);

$ 占位符是基本的字符串替换操作
会将用户输入与查询语句中的占位符进行替换
靶场测试

这里使用报错注入

http://127.0.0.1:8080/sqli/mybatis/vuln01?username=joychou' and extractvalue(0x0a,concat(0x0a,(select database()))) %23

java-sec-code中的sql注入_第1张图片
使用数据库监控插件查看执行语句,无过滤 ,直接替换执行
在这里插入图片描述

2,预编译写法

@Select("select * from users where username = #{username}")
User findByUserName(@Param("username") String username);

# 占位符是预编译语句(PreparedStatement)的方式。
使用 # 占位符时,MyBatis 会自动使用预编译,将引号字符转义
当输入为joychou’数据库实际上执行的是
select * from users where username = 'joychou\'' 无法利用

Hibernate

存在漏洞的写法

username=request.getParameter("username");
String hql = "from User where username = '" + username + "'";  
Query query = session.createQuery(hql);

预编译写法

String hql = "from User where username = :username";  
Query query = session.createQuery(hql);  
query.setParameter("username", "test"); 

你可能感兴趣的:(java,sql,开发语言)