zoukankan      html  css  js  c++  java
  • XSS攻击

    1.定义

    1.1概述

    XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。

    这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限、私密网页内容、会话和cookie等各种内容。

    1.2攻击原理

    HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,<title>与</title>之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。

    2.案例说明

    2.1创建项目

    创建一个SpringBoot的项目,带入web依赖(由于代码简单,不提供源码)

    2.2创建页面和接口

    1)在资源目录下的static目录下新建页面user.html,内容如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>保存用户信息</title>
    </head>
    <body>
        <form action="/user/save" method="post">
            <p>姓名:<input name="name"/></p>
            <p>年龄:<input name="age"/></p>
            <p>电话:<input name="phone"/></p>
            <input type="submit" value="保存" />
        </form>
    </body>
    </html>

    2)新建用户实体User:

    package com.zys.springboottestexample.entity;
    
    import lombok.Data;
    
    @Data
    public class User {
        private Integer id;
        private  String name;
        private String phone;
        private Integer age;
    }

    3)新建controller的接口:

    package com.zys.springboottestexample.controller;
    
    import com.zys.springboottestexample.entity.User;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @PostMapping("/save")
        public String save(User user){
            System.out.println(user);
            return user.getName();
        }
    
    }

    然后启动项目。访问localhost:8080/user.html

    2.3正常提交表单

    按照正常的逻辑填写表单信息,如下:

    提交后返回了用户的姓名。

    2.4非法提交表单

    假如不按照正常的逻辑填写表单内容,会发生什么?按下图填写:

     请注意,在姓名的输入框中输入的是js的代码(script标签及内容)。点击提交后,浏览器会出现弹框:

    明明是返回的用户姓名,却惊现弹框,不是我们想要的结果。

    这就是XSS攻击,黑客通过这些漏洞可以攻击我们的系统,造成系统瘫痪等严重后果。必须要防止此类攻击。

    3.防止XSS攻击

    3.1AntiSamy介绍

    AntiSamy是OWASP的一个开源项目,通过对用户输入的HTML/CSS/JavaScript等内容进行检验和清理,确保输入符合应用规范,被广泛应用于Web服务对存储型和反射型XSS的防御中。

    3.2AntiSamy入门

    1)导入依赖

    <dependency>
        <groupId>org.owasp.antisamy</groupId>
        <artifactId>antisamy</artifactId>
        <version>1.6.4</version>
    </dependency>

    2)新建策略文件

    当导入antisamy的jar后,在左侧的jar中可看到其有许多xml文件,这些都是策略文件

    antisamy.xml文件复制并粘贴到资源目录下并重命名为antisamy-config.xml。此文件就包含了大部分的策略,需要时自定义添加,这里不做修改

    3)对参数进行过滤

    创建一个类XssRequestWrapper,继承HttpServletRequestWrapper类,重写getParameterValues方法。在getParameterValues方法中需要对参数的值进行过滤,故再定义一个方法按策略进行过滤:

    package com.zys.springboottestexample.config;
    
    import org.owasp.validator.html.*;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.InputStream;
    
    /**
     * 对请求参数进行过滤处理
     */
    public class XssRequestWrapper extends HttpServletRequestWrapper {
    
        //获取策略对象
        public static Policy policy = null;
    
        static {
            try {
                InputStream stream = XssRequestWrapper.class.getClassLoader().getResourceAsStream("antisamy-config.xml");
                policy = Policy.getInstance(stream);
            } catch (PolicyException e) {
                e.printStackTrace();
            }
        }
    
        public XssRequestWrapper(HttpServletRequest request) {
            super(request);
        }
    
        /**
         * 获取所有的参数,进行过滤
         *
         * @param name 参数key,super.getParameterValues(name)可以获取对应的值
         * @return
         */
        @Override
        public String[] getParameterValues(String name) {
            String[] parameterValues = super.getParameterValues(name);
            if (parameterValues == null) {
                return null;
            }
            //遍历参数的值,过滤后放到新数组中
            String[] newValues = new String[parameterValues.length];
            for (int i = 0; i < parameterValues.length; i++) {
                newValues[i] = filterText(parameterValues[i]);
            }
            return newValues;
        }
    
        /**
         * 根据策略过滤字符信息,非法字符直接删掉
         *
         * @param text
         * @return
         */
        public String filterText(String text) {
            AntiSamy antiSamy = new AntiSamy();
            CleanResults scan = null;
            try {
                //扫描字符并按策略过滤
                scan = antiSamy.scan(text, policy);
                //得到过滤后的字符
                text = scan.getCleanHTML();
            } catch (ScanException e) {
                e.printStackTrace();
            } catch (PolicyException e) {
                e.printStackTrace();
            }
            return text;
        }
    }

    4)配置Xss过滤器

    需要使用过滤器对request请求的值进行过滤。创建类XssFilter实现Filter接口,重写doFilter方法,在放行的过程中进行过滤

    package com.zys.springboottestexample.filter;
    
    import com.zys.springboottestexample.config.XssRequestWrapper;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    /**
     * Xss过滤器
     */
    public class XssFilter implements Filter {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //对request进行封装
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            //在放行过程中对request进行过滤后
            filterChain.doFilter(new XssRequestWrapper(request),servletResponse);
        }
    }

    5)注册过滤器

    上述的过滤器并没有被Spring过滤,需要进行注册才能生效:

    package com.zys.springboottestexample.config;
    
    import com.zys.springboottestexample.filter.XssFilter;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * Xss配置类
     */
    @Configuration
    public class XssConfiguration {
    
        //配置跨站攻击过滤器
        @Bean
        public FilterRegistrationBean filterRegistrationBean(){
            //过滤器祖册器,注册自定义的过滤器
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter());
            //拦截所有的地址
            filterRegistrationBean.addUrlPatterns("/*");
            //设置过滤器的先后顺序
            filterRegistrationBean.setOrder(1);
            return filterRegistrationBean;
        }
    }

    6)测试验证。

    启动项目后,按照2.4章节不合法的提交再次输入内容,提交后不会显示弹框了,后台打印的内容中其name也是空的,说明已经把此内容过滤掉了。

    自此入门案例已完成。

    4.自定义Xss的starter

    由于经常会使用,故将其定义为starter,在其他项目中,直接将starter放到目录中,进行install即可使用。

    自定义的starter和上述的代码差别不大,在此略。源码:https://github.com/zhongyushi-git/zxh-starter-collection.git

    使用此starter方式:

    <dependency>
           <groupId>com.zxh</groupId>
           <artifactId>xss-spring-boot-starter</artifactId>
           <version>1.0-SNAPSHOT</version>
    </dependency>

    注意:在XssRequestWrapper读取决策文件中,必须使用getResourceAsStream,不能使用getResource,否则打成jar后被其他项目依赖,会提示文件找不到的错误。这是个大坑!

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    Java ListIterator(迭代器)
    java 异常 throw
    java iterator(迭代器)
    java list
    type Iterator does not take parameters
    Java 容器的打印
    java 添加一组元素
    Java 容器的基本概念
    软件
    java 学习网站
  • 原文地址:https://www.cnblogs.com/zys2019/p/14994092.html
Copyright © 2011-2022 走看看