Web安全头号大敌XSS漏洞解决最佳实践

Posted IT技术小咖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web安全头号大敌XSS漏洞解决最佳实践相关的知识,希望对你有一定的参考价值。

XSS
XSS
代码攻击及危害分析
——> <script
快速创建 springboot 应用:
     <groupId>org.owasp.antisamy</groupId>
     <artifactId>antisamy</artifactId>
     <version>1.5.7</version>
* @program: xss-demo* @author: Mr.Zhang* @create: 2021-02-21 15:45**/ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletRequest req = (HttpServletRequest) request; String path = req.getServletPath(); //注解配置的是urlPatterns="/*"(过滤所有请求),所以这里对不需要过滤的静态资源url,作忽略处理(大家可以依照具体需求配置) String[] exclusionsUrls = ".js", ".gif", ".jpg", ".png", ".css", ".ico"; for (String str : exclusionsUrls) if (path.contains(str)) chain.doFilter(request, response); return; chain.doFilter(new XssRequestWrapper(httpServletRequest), response); * @program: xss-demo* @author: Mr.Zhang* @create: 2021-02-21 15:46**/ public XssRequestWrapper(HttpServletRequest request) super(request); /** * 获取策略文件,直接使用jar中自带的ebay策略文件 */ private static InputStream inputStream = XssRequestWrapper.class.getClassLoader() .getResourceAsStream("antisamy-ebay.xml"); private static Policy policy = null; static try // 使用静态代码块处理策略对象的创建 policy = Policy.getInstance(inputStream); catch (PolicyException e) e.printStackTrace(); /** * 使用AntiSamy进行过滤数据 * @param html * @return */ private String xssClean(String html) String cleanHTML = ""; try AntiSamy antiSamy = new AntiSamy(); CleanResults scan = antiSamy.scan(html, policy); cleanHTML = scan.getCleanHTML(); catch (ScanException e) e.printStackTrace(); catch (PolicyException e) e.printStackTrace(); return cleanHTML; /** * 重写处理请求参数的方法 * @param name * @return */ @Override public String[] getParameterValues(String name) String[] values = super.getParameterValues(name); // 判断参数有值,如果没有值,直接返回 if (values == null) return null; // 遍历参数数组,使用AntiSamy进行过滤 int len = values.length; String[] newValues = new String[len]; for (int i = 0; i < len; i++) // 过滤前的数据 log.info("使用AntiSamy进行过滤清理,过滤清理之前的数据:", values[i]); // 进行过滤 newValues[i] = xssClean(values[i]); // 过滤后的数据 log.info("使用AntiSamy进行过滤清理,过滤清理之后的数据:", newValues[i]); //返回过滤后的结果 return newValues; /** * 重写处理json数据的方法 * @return * @throws IOException */ @Override public ServletInputStream getInputStream() throws IOException // 读取流 BufferedReader reader = new BufferedReader( new InputStreamReader(super.getInputStream(), "UTF-8")); // 获取json格式的数据 StringBuilder sb = new StringBuilder(); String inputStr; while ((inputStr = reader.readLine()) != null) sb.append(inputStr); // 把json转为map Map map = JSON.parseObject(sb.toString(), Map.class); // 过滤前 log.info("json过滤前:", sb.toString()); // 对map中的value值进行AntiSamy的过滤 map.keySet().forEach(k -> map.put(k, xssClean(map.get(k).toString())); ); // 过滤后 String json = JSON.toJSONString(map); log.info("json过滤后:", json); // 把json数据转为流的格式进行返回 ByteArrayInputStream bais = new ByteArrayInputStream(json.getBytes()); return new ServletInputStream() @Override public boolean isFinished() return false; @Override public boolean isReady() return false; @Override public void setReadListener(ReadListener listener) @Override public int read() throws IOException return bais.read(); ; * @program: xss-demo* @author: Mr.Zhang* @create: 2021-02-21 15:58**/ /** * 配置xss过滤器 * @return */ @Bean public FilterRegistrationBean create() FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.setOrder(1); return filterRegistrationBean; * @program: xss-demo* @author: Mr.Zhang* @create: 2021-02-21 15:42 private int id; private String name; private int age;* @program: xss-demo* @author: Mr.Zhang* @create: 2021-02-21 15:43**/ /** * 表单 * @param user * @return */ @PostMapping("save") public String save(User user) log.info("name=, age=", user.getName(), user.getAge()); return JSON.toJSONString(user); /** * json数据格式请求体 * @param user * @return */ @PostMapping("json") public String saveJson(@RequestBody User user) log.info("user=", user.toString()); return JSON.toJSONString(user); content="form-action \'self\';">
CSP 常见可选策略设置如下:
策略
含义
default-src http: https: ;
只能通过外联的方式引用 js 和 css
default-src \'self\' http://smart4j.cn/
只能在指定的域下加载文(包含 img)
form-action \'self\'\';
form 表单的只能在指定域提交
script-src \'self\';
只限制 js 文件在同域加载文件
report-uri /report;
向指定uri发送违规报告(不支持 meta 方式)


加油


精彩推荐 #

 分布式系统「全链路日志追踪」实战之 RestTemplate & Feign

  小白都能看得懂的服务调用链路追踪设计与实现

  [三步法] 可视化分析定位线上 JVM 问题

  从 Java 代码如何运行聊到 JVM 和对象的创建-分配-定位-布局-垃圾回收

深入了解 Spring 中的事务(从核心注解和类入手)



 "在看"吗,赶快分享和收藏吧

XSS漏洞简介

0x01.什么是XSS

全称:Cross Site Script

中文名称:跨站脚本

按英文缩写应该是CSS,为了与层叠样式表CSS做区分,安全行业就取名为XSS。

XSS是客户端安全的头号大敌,常见的危害有:盗取cookie,钓鱼,制造蠕虫等。

XSS其实是客户端代码的注入,通常注入代码是JAVAScript

区别于命令注入,SQL注入等服务端代码注入

概念:黑客通过 ‘HTML注入’ 篡改网页,插入恶意脚本,当用户在浏览网页时,实现控制用户浏览器行为的一种攻击方式。


0x02.xss的分类


存储型:一般在查看留言,看评论的时候触发。

下面我们分析下存储型XSS的攻击过程:


1.用户打开浏览器,访问了嵌入xss脚本的页面

2.浏览器向web应用程序请求页面。

3.页面中的留言存储在数据库中,需要web应用程序查询数据库

4.数据库会将携带xss脚本的留言返回给web应用程序

5.web应用程序返回给浏览器

6.显示在浏览器上,触发XSS。

这里xss脚本是存储在数据库中,那么是什么时候保存到数据库中的呢?。肯定是黑客构造XSS脚本并写入到数据库中。

1.黑客精心构造XSS脚本提交给web应用程序。

2.web应用程序将恶意留言保存到数据库中。

3.其他用户或者管理员在查看留言时就跟前面展示的一样触发XSS。

存储型xss关键点:xss脚本内容是存储在数据库中

XSS漏洞简介


反射型:一般需要我们访问携带XSS脚本的链接触发,xss在URL的参数中,比如通过邮件,聊天工具发送链接,只要我们打开这个链接就触发了XSS,反射型xss可以在链接中明显的看到xss脚本。

下面我们分析反射性XSS的攻击过程:

  1. 用户访问问含有xss脚本的链接

  2. 浏览器向后端web程序发送请求

  3. 后端web程序将URL中的XSS数据脚本写入响应页面

  4. 返回给浏览器

  5. 浏览器渲染响应页面,触发XSS

  6. XSS漏洞简介


DOM型:与反射型需要访问携带XSS脚本的链接触发,xss脚本在URL的哈希中。

下面我们分析DOM型XSS的攻击过程:

1.用户访问含有XSS脚本的链接

2.浏览器通过JAvascript从URL中提取XSS的脚本内容

3.写入DOM中触发XSS


0x03.三种XSS比较


以上是关于Web安全头号大敌XSS漏洞解决最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

XSS攻击原理与解决方法

浅谈xss攻击原理与解决方法

色素沉积 美白族的头号大敌

xss攻击原理

XSS攻击原理及防御措施

惯性思维是排错的大敌