前言在我们日常的开发中,很多小伙伴往往会忽略安全漏洞,认为只要业务逻辑正常实现就可以了。其实安全才是最重要的。本文将和大家一起学习常见的安全漏洞,希望对大家有所帮助。本文如有错误,希望大家指出,谢谢~1.SQL注入1.1什么是SQL注入?SQL注入是一种代码注入技术,一般用于攻击Web应用。它通过在Web应用界面中传递一些特殊的参数字符来欺骗应用服务器,执行恶意的SQL命令来达到非法获取系统信息的目的。是目前黑客攻击数据库最常用的手段之一。1.2SQL注入是如何进行攻击的?举一个常见的业务场景:在Web表单的搜索框中输入员工姓名,然后在后台查询对应姓名的员工。这种场景一般是前端页面传递一个name参数name给后台,然后后台通过SQLname="snail";//SQL="select*fromstaffwherename="+name;从前端传递过来;//根据前端传过来的name参数,查询数据库employee表staff,因为SQL是直接拼接的,如果我们完全信任前端传过来的参数。如果前端传了这样一个参数''或'1'='1',SQL就会变成紫色。select*fromstaffwherename=''or'1'='1';这条SQL会查出所有的员工信息,姜子要求用户越权。请求者可以获得所有员工的信息,其他用户信息已经暴露。1.3如何防止SQL注入问题1.3.1使用#{}代替${}在MyBatis中,使用#{}代替${},可以很大程度上防止sql注入。因为#{}是参数占位符,对于字符串类型,会自动添加"",对于其他类型,则不会添加。由于Mybatis使用预编译,后面的参数不会和SQL一起编译,所以一定程度上防止了SQL注入。${}是一个简单的字符串替换。无论字符串是什么,它都会被解析成任何内容。存在SQL注入风险。1.3.2不要暴露不必要的日志或安全信息,比如避免直接响应一些sql异常信息。如果SQL出现异常,不暴露信息给用户,可以自定义异常响应方法,filterunion,or等数据库关键字1.3.4适当的权限控制查询信息时,首先检查当前是否有用户有这个权限。比如在实现代码的时候,可以让用户额外传入一个企业ID,或者获取当前用户的session信息等,在查询之前先判断当前用户是否属于这个企业等。有这是查询员工的权限。2.JSON反序列化漏洞——如Fastjson安全漏洞2.1什么是JSON序列化,JSON序列化Serialization:将对象转换为字节序列的过程Deserialization:将字节序列还原为Java对象的过程JsonSerialization是将对象转换为字符串是Json格式,JSON反序列化就是将一个Json字符串转化为一个对象2.2JSON反序列化漏洞是如何被攻击的?不安全的反序列化可能导致远程代码执行、重放攻击、注入攻击或特权升级攻击。在Fastjson频繁爆出安全漏洞之前,我们先来分析一下fastjson1.2.24版本的一个反序列化漏洞。常见的利用该漏洞的方式是通过jndi注入实现RCE。我们先来看一个简单的fastjson反序列化的例子:}publicintgetAge(){returnage;}publicvoidsetAge(intage){System.out.println("调用了age方法");this.age=age;}publicstaticvoidmain(String[]args){Stringstr="{\"@type\":\"cn.eovie.bean.User\",\"age\":26,\"name\":\"捡蜗牛的小男孩\"}";Useruser=JSON.parseObject(str,User.class);}}运行结果:调用age方法,调用name方法,添加@type属性调用对应对象的setXXX方法,@type表示指定反序列化到某个类中。如果我们能够找到一个类,并且通过我们精心构造的这个类的某个setXXX方法能够完成命令的执行,就可以达到攻击的目的。com.sun.rowset.JdbcRowSetImpl就是类似这样一个类,它有两个set方法,分别是setAutoCommit和setDataSourceName"有兴趣的朋友可以看看它的源码publicvoidsetDataSourceName(Stringvar1)throwsSQLException{if(this.getDataSourceName()!=null){if(!this.getDataSourceName().equals(var1)){super.setDataSourceName(var1);this.conn=null;this.ps=null;this.rs=null;}}else{super.setDataSourceName(var1);}}publicvoidsetAutoCommit(booleanvar1)throwsSQLException{if(this.conn!=null){this.conn.setAutoCommit(var1);}else{this.conn=this.connect();this.conn.setAutoCommit(var1);}}privateConnectionconnect()throwsSQLException{if(this.conn!=null){returnthis.conn;}elseif(this.getDataSourceName()!=null){try{InitialContextvar1=newInitialContext();DataSourcevar2=(DataSource)var1.lookup(this.getDataSourceName());returnthis.getUsername()!=null&&!this.getUsername().equals("")?var2.getConnection(this.getUsername(),this.getPassword()):var2.getConnection();}catch(NamingExceptionvar3){thrownewSQL异常(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());}}else{returnthis.getUrl()!=null?DriverManager.getConnection(this.getUrl(),this.getUsername(),this.getPassword()):null;}}setDataSourceName只是设置dataSourceName的值,setAutoCommit中有一个connect操作,connect方法中有一个典型的jndilookup方法调用,参数就是setDataSourceName中设置的dataSourceName因此,易受攻击的反序列化代码可以这样实现:sun.jndi.rmi.object.trustURLCodebase","true");//RMIStringpayload2="{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://localhost:1099/Exploit\","+"\"autoCommit\":true}";JSONObject.parseObject(payload2);}}漏洞复现过程如下:参考代码源在这里,fastjson漏洞代码测试(https://github.com/earayu/fastjson_jndi_poc)如何解决json反序列化漏洞问题。可以升级版本,比如fastjson的更高版本,增强开启AutoType时fastjson的安全性,增加AutoType黑名单等,都是为了应对这些安全漏洞。反序列化有fastjson、gson、jackson等类型,可以替代其他类型。升级+开启安全模式3.XSS攻击3.1什么是XSS?XSS攻击的全称是Cross-SiteScripting(跨站脚本),会和CascadingStyleSheets(CSS)的缩写混淆,所以有人将跨站脚本攻击简称为XSS。它是指恶意攻击者在网页中插入恶意的html代码。当用户浏览页面时,会执行网页中嵌入的html代码,从而达到恶意攻击用户的特殊目的。XSS攻击一般分为三种类型:存储型、反射型、DOM型XSS》3.2XSS是如何攻击的?以反射型为例,流程图如下:我们来做一些简单的代码示例,首先是所有,正常的html页面如下:
