如何有效防止sql注入

55次阅读
没有评论

共计 3262 个字符,预计需要花费 9 分钟才能阅读完成。

自动写代码机器人,免费开通

如何有效防止 sql 注入?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面丸趣 TV 小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

@RestController
public class Controller {
 
 @Autowired
 SqlInject sqlInject;
 
 @GetMapping(list)
 public List Course  courseList(@RequestParam( studentId) String studentId){ List Course  orders = sqlInject.orderList(studentId);
 return orders;
 }
}
@Service
public class SqlInject {
 @Autowired
 private JdbcTemplate jdbcTemplate;
 
 public List Course  orderList(String studentId){
 String sql =  select id,course_id,student_id,status from course where student_id =  + studentId;
 return jdbcTemplate.query(sql,new BeanPropertyRowMapper(Course.class));
 }
}

二 注入攻击演示

1. 正常情况下查询一个学生所选课程及完成情况只需要传入 student_id,便可以查到相关数据。

如何有效防止 sql 注入

根据响应结果,我们很快便能写出对应的 sql,如下:

select id,course_id,student_id,status 
from course 
where student_id = 4

2. 如果我们想要获取这张表的所有数据,只需要保证上面这个 sql 的 where 条件恒真就可以了。

select id,course_id,student_id,status 
from course 
where student_id = 4 or 1 = 1

请求接口的时候将 studendId 设置为 4 or 1 = 1,这样这条 sql 的 where 条件就恒真了。sql 也就等同于下面这样

select id,course_id,student_id,status 
from course

请求结果如下,我们拿到了这张表的所有数据

如何有效防止 sql 注入

3. 查询 mysql 版本号,使用 union 拼接 sql

union select 1,1,version(),1

如何有效防止 sql 注入

4. 查询数据库名

union select 1,1,database(),1

如何有效防止 sql 注入

5. 查询 mysql 当前用户的所有库

union select 1,1, (SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata) schemaName,1

如何有效防止 sql 注入

看完上面这些演示后,你害怕了吗?你所有的数据配置都完全暴露出来了,除此之外,还可以完成很多操作,更新数据、删库、删表等等。

三 如何防止 sql 注入

1. 代码层防止 sql 注入攻击的最佳方案就是 sql 预编译

public List Course  orderList(String studentId){
 String sql =  select id,course_id,student_id,status from course where student_id = ? 
 return jdbcTemplate.query(sql,new Object[]{studentId},new BeanPropertyRowMapper(Course.class));
}

这样我们传进来的参数 4 or 1 = 1 就会被当作是一个 student_id,所以就不会出现 sql 注入了。

2. 确认每种数据的类型,比如是数字,数据库则必须使用 int 类型来存储

3. 规定数据长度,能在一定程度上防止 sql 注入

4. 严格限制数据库权限,能最大程度减少 sql 注入的危害

5. 避免直接响应一些 sql 异常信息,sql 发生异常后,自定义异常进行响应

6. 过滤参数中含有的一些数据库关键词

@Component
public class SqlInjectionFilter implements Filter {
 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)servletRequest;
 HttpServletRequest res=(HttpServletRequest)servletResponse;
 // 获得所有请求参数名
 Enumeration params = req.getParameterNames();
 String sql =  
 while (params.hasMoreElements()) {
 //  得到参数名
 String name = params.nextElement().toString();
 //  得到参数对应值
 String[] value = req.getParameterValues(name);
 for (int i = 0; i   value.length; i++) { sql = sql + value[i];
 }
 }
 if (sqlValidate(sql)) {
 throw new IOException( 您发送请求中的参数中含有非法字符 
 } else { chain.doFilter(servletRequest,servletResponse);
 }
 }
 /**
 *  关键词校验
 * @param str
 * @return
 */
 protected static boolean sqlValidate(String str) {
 //  统一转为小写
 str = str.toLowerCase();
 //  过滤掉的 sql 关键字,可以手动添加
 String badStr =  |and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|  +
  char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like |and|exec|execute|insert|create|drop|  +
  table|from|grant|use|group_concat|column_name|  +
  information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|  +
  chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|# 
 String[] badStrs = badStr.split( \\| 
 for (int i = 0; i   badStrs.length; i++) { if (str.indexOf(badStrs[i])  = 0) {
 return true;
 }
 }
 return false;
 }
}

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注丸趣 TV 行业资讯频道,感谢您对丸趣 TV 的支持。

向 AI 问一下细节

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-04发表,共计3262字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)