array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 JAVA代码审计-XSS - 爱码网

前言

本篇记录一下java代码审计的XSS漏洞需要关注的点。

0x01 XSS漏洞分析

XSS产生

后台未对用户输入进行检查或过滤,直接把用户输入返回至前端。导致javascript代码在客户端任意执行。

代码举例

public void Message(HttpServletRequest req, HttpServletResponse resp) {
        // TODO Auto-generated method stub
        String message = req.getParameter("msg");

        try {
            resp.getWriter().print(message);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 }

这里获取的msg字段原封不动返回出来,如果是js代码,也会解析执行,造成反射型xss漏洞;

JAVA代码审计-XSS

JAVA代码审计-XSS

防御XSS

根据漏洞原因,可以采用过滤输入的方法来进行防御:

  • 输入转义进行存储
  • 过滤特殊字符
  • 前段输入限制< `等特殊字符

具体防御采用的方式可以是:

  • 全局过滤器,设置filter:

    <filter>  
            <filter-name>XssSafe</filter-name>  
            <filter-class>XssFilter</filter-class>  
    </filter>  
    <filter-mapping>  
            <filter-name>XssSafe</filter-name>  
            <url-pattern>/*</url-pattern>  
    </filter-mapping>
    

    这里要注意的是,我们的配置是/*而不是/< url-pattern>/</url-pattern> 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url,而< url-pattern>/*</url-pattern>会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js*.html等)。

    然后编写过滤器的内容就行了,这个网上有写好的,可以直接拿来用,如下:

    //XssFilter实现:
    
    public class XssFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
        }
    
    }
    //XssHttpServletRequestWrapper实现
    
    public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
        public XssHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }
    
        @SuppressWarnings("rawtypes")
        public Map<String,String[]> getParameterMap(){
            Map<String,String[]> request_map = super.getParameterMap();
            Iterator iterator = request_map.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry me = (Map.Entry)iterator.next();
                String[] values = (String[])me.getValue();
                for(int i = 0 ; i < values.length ; i++){
                    values[i] = xssClean(values[i]);
                }
            }
    
            return request_map;
        }
         public String[] getParameterValues(String paramString)
          {
            String[] arrayOfString1 = super.getParameterValues(paramString);
            if (arrayOfString1 == null)
              return null;
            int i = arrayOfString1.length;
            String[] arrayOfString2 = new String[i];
            for (int j = 0; j < i; j++){
                arrayOfString2[j] = xssClean(arrayOfString1[j]);
            }
            return arrayOfString2;
          }
    
          public String getParameter(String paramString)
          {
            String str = super.getParameter(paramString);
            if (str == null)
              return null;
            return xssClean(str);
          }
    
          public String getHeader(String paramString)
          {
            String str = super.getHeader(paramString);
            if (str == null)
              return null;
            str = str.replaceAll("\r|\n", "");
            return xssClean(str);
          }
    
    
          private String xssClean(String value) {
            //ClassLoaderUtils.getResourceAsStream("classpath:antisamy-slashdot.xml", XssHttpServletRequestWrapper.class)
            if (value != null) {
                // NOTE: It's highly recommended to use the ESAPI library and
                // uncomment the following line to
                // avoid encoded attacks.
                // value = encoder.canonicalize(value);
                value = value.replaceAll("\0", "");
    
                // Avoid anything between script tags
                Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>",
                        Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid anything in a src='...' type of expression
                scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
                // Avoid anything in a href='...' type of expression
                scriptPattern = Pattern.compile("href[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
                                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                            | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
    
    
                // Remove any lonesome </script> tag
                scriptPattern = Pattern.compile("</script>",
                        Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Remove any lonesome <script ...> tag
                scriptPattern = Pattern.compile("<script(.*?)>",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid eval(...) expressions
                scriptPattern = Pattern.compile("eval\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid expression(...) expressions
                scriptPattern = Pattern.compile("expression\\((.*?)\\)",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid javascript:... expressions
                scriptPattern = Pattern.compile("javascript:",
                        Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid vbscript:... expressions
                scriptPattern = Pattern.compile("vbscript:",
                        Pattern.CASE_INSENSITIVE);
                value = scriptPattern.matcher(value).replaceAll("");
    
                // Avoid onload= expressions
                scriptPattern = Pattern.compile("onload(.*?)=",
                        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
                                | Pattern.DOTALL);
                value = scriptPattern.matcher(value).replaceAll("");
            }  
              return value; 
              }
    }
    
  • 使用工具类xssProtect

    下载对应jar包放入lib目录导入:https://code.google.com/archive/p/xssprotect/

    简单用法:

    protectedAgainstXSS(String html){StringReader reader = new StringReader(html); StringWriter writer = new StringWriter();
      try {
          // 从“ html”变量解析传入的字符串
          HTMLParser.process( reader, writer, new XSSFilter(), true );
    
          // 返回经过解析和处理的字符串
          return writer.toString();
      } catch (HandlingException e) {
      }
    }
    

    具体的使用方式可以参考:https://www.iteye.com/blog/liuzidong-1744023

  • 使用ESAPI可以防御大多数web攻击

    pom导入:

    <dependency>
        <groupId>org.owasp.esapi</groupId>
        <artifactId>esapi</artifactId>
        <version>2.2.1.1</version>
    </dependency>
    

    获取输入参数前进行一次实体编码:

     public void Message(HttpServletRequest req, HttpServletResponse resp) {
            // TODO Auto-generated method stub
            String message = req.getParameter("msg");
            String s = ESAPI.encoder().encodeForHTML(message);  //进行实体编码
    
            try {
                resp.getWriter().print(s);
    
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
    }
    

0x02 审计XSS漏洞

setAttribute

setAttribute方法用来在同一个request周期中保存变量使用,使用时再通过getAttribute方法取出。

@WebServlet("/demo")
public class xssServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");// 设置响应类型
        String content = request.getParameter("content");  //获取content传参数据
        request.setAttribute("content", content);  //content共享到request域
        request.getRequestDispatcher("/WEB-INF/pages/xss.jsp").forward(request, response);  //转发到xxs.jsp页面中

    }
}

jsp中:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    ${requestScope.content}
</head>
<body>

</body>
</html>

ModelAndView

ModelAndView可以返回参数到指定页面的request作用域中或者指定返回的页面名称。

@RequestMapping("/test")
public ModelAndView test(){
    ModelAndView mav=new ModelAndView("hello");
    mav.addObject("time", new Date());
    mav.getModel().put("name", "caoyc");
    
    return mav;
}

jsp中:

time:${requestScope.time} <br/>
name:${name }

我们可以通过观察ModelAndView中传入的参数是不是可控的或者有没有什么过滤来进行审计。

可以看到不论是利用哪种方法,最后都需要取出并输出,现在用的比较广泛的除了<%out.println(msg);%>就是el表达式,也就是说在审计xss中也可以从el表达式入手。

参考

https://xz.aliyun.com/t/6937

https://www.cnblogs.com/nice0e3/p/13655552.html

相关文章:

  • 2021-07-08
  • 2021-11-21
  • 2021-08-07
  • 2019-11-10
  • 2020-10-28
  • 2019-09-28
  • 2020-10-29
  • 2019-09-28
猜你喜欢
  • 2019-09-28
  • 2021-01-04
  • 2019-02-16
  • 2018-10-09
  • 2021-11-02
  • 2020-10-26
  • 2021-11-02
  • 2021-07-15
相关资源
相似解决方案