文章目录

  • 1. XSS跨站脚本攻击
    • ①:XSS漏洞介绍
    • ②:XSS漏洞分类
    • ③:防护建议
  • 2. SQL注入攻击
    • ①:SQL注入漏洞介绍
    • ②:防护建议
  • 3. SpringBoot中如何防止XSS攻击和sql注入

1. XSS跨站脚本攻击

①:XSS漏洞介绍

跨站脚本攻击XSS是指攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被解析执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!

②:XSS漏洞分类

  • 存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie
  • 反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面
  • DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。

③:防护建议

  • 限制用户输入,表单数据规定值得类型,例如年龄只能是int,name为字母数字组合。
  • 对数据进行html encode处理。
  • 过滤或移除特殊的html标签。
  • 过滤javascript事件的标签。

2. SQL注入攻击

①:SQL注入漏洞介绍

SQL注入(SQLi)是一种注入攻击,可以执行恶意SQL语句。它通过将任意SQL代码插入数据库查询,使攻击者能够完全控制Web应用程序后面的数据库服务器。攻击者可以使用SQL注入漏洞绕过应用程序安全措施;可以绕过网页或Web应用程序的身份验证和授权,并检索整个SQL数据库的内容;还可以使用SQL注入来添加,修改和删除数据库中的记录

SQL注入漏洞可能会影响使用SQL数据库(如MySQL,Oracle,SQL Server或其他)的任何网站或Web应用程序。犯罪分子可能会利用它来未经授权访问用户的敏感数据:客户信息,个人数据,商业机密,知识产权等。SQL注入攻击是最古老,最流行,最危险的Web应用程序漏洞之一。

②:防护建议

使用mybatis#{}可以有效防止sql注入

  • 使用#{}时:
<select id="getBlogById" resultType="Blog" parameterType=”int”>select id,title,author,contentfrom blog where id=#{id}
</select>打印出执行的sql语句,会看到sql是这样的:
select id,title,author,content from blog where id = ?

不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以像#{}这样预编译成的方式就很好地避免了sql注入的问题。

mybatis是如何做到sql预编译的呢?

其实在框架底层,是jdbc中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的sql语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行一个sql时,能够提高效率,原因是sql已编译好,再次执行时无需再编译。

  • 使用${}
<select id="orderBlog" resultType="Blog" parameterType=”map”>select id,title,author,contentfrom blog order by ${orderParam}
</select>仔细观察,内联参数的格式由“#{xxx}”变为了${xxx}。如果我们给参数“orderParam”赋值为”id”,将sql打印出来,是这样的:select id,title,author,contet from blog order by id

显然,这样是无法阻止sql注入的,参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${}”这样的参数格式,所以,这样的参数需要我们在代码中手工进行处理来防止注入。

3. SpringBoot中如何防止XSS攻击和sql注入

话不多说,上代码

对于Xss攻击和Sql注入,我们可以通过过滤器来搞定,可根据业务需要排除部分请求

①:创建Xss请求过滤类XssHttpServletRequestWraper

代码如下:

public class XssHttpServletRequestWraper extends HttpServletRequestWrapper {Logger log = LoggerFactory.getLogger(this.getClass());public XssHttpServletRequestWraper() {super(null);}public XssHttpServletRequestWraper(HttpServletRequest httpservletrequest) {super(httpservletrequest);}//过滤springmvc中的 @RequestParam 注解中的参数public String[] getParameterValues(String s) {String str[] = super.getParameterValues(s);if (str == null) {return null;}int i = str.length;String as1[] = new String[i];for (int j = 0; j < i; j++) {//System.out.println("getParameterValues:"+str[j]);as1[j] = cleanXSS(cleanSQLInject(str[j]));}log.info("XssHttpServletRequestWraper净化后的请求为:==========" + as1);return as1;}//过滤request.getParameter的参数public String getParameter(String s) {String s1 = super.getParameter(s);if (s1 == null) {return null;} else {String s2 = cleanXSS(cleanSQLInject(s1));log.info("XssHttpServletRequestWraper净化后的请求为:==========" + s2);return s2;}}//过滤请求体 json 格式的@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ());return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) { }};}public   String inputHandlers(ServletInputStream servletInputStream){StringBuilder sb = new StringBuilder();BufferedReader reader = null;try {reader = new BufferedReader(new InputStreamReader(servletInputStream, Charset.forName("UTF-8")));String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (servletInputStream != null) {try {servletInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}return  cleanXSS(sb.toString ());}public String cleanXSS(String src) {String temp = src;src = src.replaceAll("<", "<").replaceAll(">", ">");src = src.replaceAll("\\(", "(").replaceAll("\\)", ")");src = src.replaceAll("'", "'");src = src.replaceAll(";", ";");//bgh 2018/05/30  新增/**-----------------------start--------------------------*/src = src.replaceAll("<", "& lt;").replaceAll(">", "& gt;");src = src.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41");src = src.replaceAll("eval\\((.*)\\)", "");src = src.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");src = src.replaceAll("script", "");src = src.replaceAll("link", "");src = src.replaceAll("frame", "");/**-----------------------end--------------------------*/Pattern pattern = Pattern.compile("(eval\\((.*)\\)|script)",Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(src);src = matcher.replaceAll("");pattern = Pattern.compile("[\\\"\\'][\\s]*javascript:(.*)[\\\"\\']",Pattern.CASE_INSENSITIVE);matcher = pattern.matcher(src);src = matcher.replaceAll("\"\"");// 增加脚本src = src.replaceAll("script", "").replaceAll(";", "")/*.replaceAll("\"", "").replaceAll("@", "")*/.replaceAll("0x0d", "").replaceAll("0x0a", "");if (!temp.equals(src)) {// System.out.println("输入信息存在xss攻击!");// System.out.println("原始输入信息-->" + temp);// System.out.println("处理后信息-->" + src);log.error("xss攻击检查:参数含有非法攻击字符,已禁止继续访问!!");log.error("原始输入信息-->" + temp);throw new CustomerException("xss攻击检查:参数含有非法攻击字符,已禁止继续访问!!");}return src;}//输出public void outputMsgByOutputStream(HttpServletResponse response, String msg) throws IOException {ServletOutputStream outputStream = response.getOutputStream(); //获取输出流response.setHeader("content-type", "text/html;charset=UTF-8"); //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码byte[] dataByteArr = msg.getBytes("UTF-8");// 将字符转换成字节数组,指定以UTF-8编码进行转换outputStream.write(dataByteArr);// 使用OutputStream流向客户端输出字节数组}// 需要增加通配,过滤大小写组合public String cleanSQLInject(String src) {String lowSrc = src.toLowerCase();String temp = src;String lowSrcAfter = lowSrc.replaceAll("insert", "forbidI").replaceAll("select", "forbidS").replaceAll("update", "forbidU").replaceAll("delete", "forbidD").replaceAll("and", "forbidA").replaceAll("or", "forbidO");if (!lowSrcAfter.equals(lowSrc)) {log.error("sql注入检查:输入信息存在SQL攻击!");log.error("原始输入信息-->" + temp);log.error("处理后信息-->" + lowSrc);throw new CustomerException("sql注入检查:参数含有非法攻击字符,已禁止继续访问!!");}return src;}}

②:把请求过滤类XssHttpServletRequestWraper添加到Filter中,注入容器

@Component
public class XssFilter implements Filter {Logger log  = LoggerFactory.getLogger(this.getClass());// 忽略权限检查的url地址private final String[] excludeUrls = new String[]{"null"};public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) arg0;HttpServletResponse response = (HttpServletResponse) arg1;String pathInfo = req.getPathInfo() == null ? "" : req.getPathInfo();//获取请求url的后两层String url = req.getServletPath() + pathInfo;//获取请求你ip后的全部路径String uri = req.getRequestURI();//注入xss过滤器实例XssHttpServletRequestWraper reqW = new XssHttpServletRequestWraper(req);//过滤掉不需要的Xss校验的地址for (String str : excludeUrls) {if (uri.indexOf(str) >= 0) {arg2.doFilter(arg0, response);return;}}//过滤arg2.doFilter(reqW, response);}public void destroy() {}public void init(FilterConfig filterconfig1) throws ServletException {}
}

上述代码已经可以完成 请求参数、JSON请求体 的过滤,但对于json请求体还有其他的方式实现,有兴趣的请看下面的扩展!

扩展:还可以重写spring中的MappingJackson2HttpMessageConverter来过滤Json请求体

因为请求体在进出Contoroller时,会经过MappingJackson2HttpMessageConverter的一个转换,把请求体转换成我们需要的json格式,所以可以在这里边做一些修改!

@Configuration
public class MyConfiguration {@Beanpublic MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){//自定义转换器MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();//转换器日期格式设置ObjectMapper objectMapper = new ObjectMapper();SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");objectMapper.setDateFormat(smt);converter.setObjectMapper(objectMapper);//转换器添加自定义Module扩展,主要是在这里做XSS过滤的!!,其他的是其他业务,不用看SimpleModule simpleModule = new SimpleModule();//添加过滤逻辑类!simpleModule.addDeserializer(String.class,new StringDeserializer());converter.getObjectMapper().registerModule(simpleModule);//设置中文编码格式List<MediaType> list = new ArrayList<>();list.add(MediaType.APPLICATION_JSON_UTF8);converter.setSupportedMediaTypes(list);return converter;}}

真正的过滤逻辑类StringDeserializer

//检验请求体的参数
@Component
public class StringDeserializer extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {String str = jsonParser.getText().trim();//sql注入拦截if (sqlInject(str)) {throw new CustomerException("参数含有非法攻击字符,已禁止继续访问!");}return xssClean(str);}public boolean sqlInject(String str) {if (StringUtils.isEmpty(str)) {return false;}//去掉'|"|;|\字符str = org.apache.commons.lang3.StringUtils.replace(str, "'", "");str = org.apache.commons.lang3.StringUtils.replace(str, "\"", "");str = org.apache.commons.lang3.StringUtils.replace(str, ";", "");str = org.apache.commons.lang3.StringUtils.replace(str, "\\", "");//转换成小写str = str.toLowerCase();//非法字符String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert","alter", "drop"};//判断是否包含非法字符for (String keyword : keywords) {if (str.indexOf(keyword) != -1) {return true;}}return false;}//xss攻击拦截public String xssClean(String value) {if (value == null || "".equals(value)) {return value;}//非法字符String[] keywords = {"<", ">", "<>", "()", ")", "(", "javascript:", "script","alter", "''","'"};//判断是否包含非法字符for (String keyword : keywords) {if (value.indexOf(keyword) != -1) {throw new CustomerException("参数含有非法攻击字符,已禁止继续访问!");}}return value;}
}

使用这种形式也可以完成json请求体的过滤,但个人更推荐使用XssHttpServletRequestWraper的形式来完成xss过滤!!

springboot防止XSS攻击和sql注入相关推荐

  1. SpringBoot 防止XSS攻击和SQL攻击拦截器(Filter)

    什么是SQL攻击.什么是XSS攻击 SQL 攻击:把SQL命令插入到Web表单并提交,欺骗服务器执行恶意的SQL命令. XSS 攻击:向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏 ...

  2. 浅析:XSS攻击、SQL注入攻击和CSRF攻击

    1.XSS(Cross Site Script)攻击 跨站脚本攻击,是在用户浏览网页时向用户浏览器中执行恶意脚本的攻击方式. 跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意脚本的链接以 ...

  3. 08蚂蚁-互联网安全架构——1.XSS攻击,SQL注入攻击,Http请求防盗链,CSRF请求攻击,忘记密码暴力破解,上传文件漏洞

    常见Web安全漏洞 XSS攻击 什么是XSS攻击手段 XSS攻击使用Javascript脚本注入进行攻击 例如在提交表单后,展示到另一个页面,可能会受到XSS脚本注入,读取本地cookie远程发送给黑 ...

  4. 一文搞懂│XSS攻击、SQL注入、CSRF攻击、DDOS攻击、DNS劫持

    ✨ 目录

  5. WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

    对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...

  6. android 访问服务器sql_XSS 攻击、CSRF 攻击、SQL 注入、流量劫持(DNS 劫持、HTTP 劫持)—— 浏览器安全

    今天看了 jsliang 大佬关于网络安全的文章,为了加深一下印象,自己动手写一下. 主要参考文章:网络安全 --- jsliang XSS攻击 XSS(Cross Site Script)跨站脚本攻 ...

  7. 安全测试之xss攻击和mysql注入

    xss概念: xss(Cross Site Script)跨站脚本攻击,为不和层叠样式表(css)混淆,写为xss 存在位置:web应用系统最常见软件安全漏洞 后果:代码植入到系统页面,篡改数据.盗取 ...

  8. mysql注入内置函数_PHP面试之mysql内置函数,xss漏洞,sql注入

    面试被问到: 1. MySql有哪些常用聚合函数: count().sum().max().min().avg().group_concat() mysql还有常用的函数: (1)数值函数: Abs( ...

  9. springboot testcontext @sql_举世闻名的 SQL 注入是什么?这个漫画告诉你!

     2020年最新的常问企业面试题大全以及答案 来源:jizhi.im/blog/post/sql_injection_intro 先来看一副很有意思的漫画: 相信大家对于学校们糟糕的网络环境和运维手段 ...

最新文章

  1. 数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码
  2. 帝国CMS的phomenewspic/ecmsinfo标签详解
  3. 有趣的php实例,8个必备的PHP功能实例代码
  4. pC机OracLe库磁盘坏如何恢复,电脑硬盘坏了数据能恢复吗(6步教你自己在家轻松恢复数据)...
  5. 获取springbean的几种方式
  6. Android studio吧,Android Studio 连接真机
  7. **python基础类和对象(十二)
  8. 隐藏画质代码_和平精英120帧率代码是什么?隐藏的120帧率代码更改方法技巧
  9. Python OpenCV学习笔记之:使用MOG2视频背景消除
  10. LaTeX 常用符号大全(from wikipedia)
  11. 计算机户籍管理,里诺户口管理系统
  12. Python求方差、均值、标准差
  13. ngx之日志切割 、ngx信号
  14. 小麦苗健康检查脚本说明
  15. Matlab:串联示例
  16. python与金融工程的区别_科研进阶 | 纽约大学 | 金融工程、量化金融、商业分析:Python金融工程分析...
  17. [蓝桥杯]校内培训交流会总结
  18. tuxedo错误码6_tuxedo错误解析和常用配置说明
  19. 成本管理观念的更新与成本控制新思路
  20. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]...

热门文章

  1. 解析xml_QT开发(四十四)——流方法解析XML
  2. 键盘鼠标共享效率工具-Synergy
  3. 隐藏方法不能实现多态性
  4. SQL Server 2008 R2 数据库安装
  5. 【Hadoop】HIVE 数据表 使用
  6. 首届CSS开发者大会|七牛助力前端开发
  7. 创建链路状态状态数据包
  8. 传到虚拟主机在线人数不显示的解决办法
  9. 修改centos系统默认编辑器
  10. Exchange邮箱的创建与配置