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,content from 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,content from 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注入
话不多说,上代码
Spring Boot 根底就不介绍了,举荐看这个收费教程:
https://github.com/javastacks/spring-boot-best-practice
对于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 格局的 @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ()); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public 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中,注入容器
@Componentpublic 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格局,所以能够在这里边做一些批改!
@Configurationpublic class MyConfiguration { @Bean public 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
:
//测验申请体的参数@Componentpublic class StringDeserializer extends JsonDeserializer<String> { @Override public 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过滤!!
起源:blog.csdn.net/qq_45076180/article/details/115000495
近期热文举荐:
1.1,000+ 道 Java面试题及答案整顿(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!