JAVA代审之XSS漏洞

admin 2025年5月6日09:53:41评论5 views1字数 7424阅读24分44秒阅读模式

一般来说,XSS 的危害性没有 SQL 注入的大,但是一次有效的 XSS 攻击可以做很多
事情,
比如获取 Cookie、获取用户的联系人列表、截屏、劫持等。根据服务器后端代码
的不同,
XSS 的种类也不相同,一般可以分为反射型、存储型以及和反射型相近的 DOM
型。
漏洞危害有:窃取 Cookie,键盘记录,截屏,网页挂马,命令执行。

XSS 常见触发位置

1.JSP 表达式

“<%=变量 %>”是“<% out.println(变量); %>”的简写方式,“<%=%>”用于将已声
明的变量或表达式输出到外网页中。

下面两种形式的写法实现的效果是相同的,
都是将变量输出到网页中。

形式一:

<%=msg%>
<% out.println(msg); %>

形式二:

<% String msg = request.getParameter('msg');%>
<%=msg%>

2.EL

EL(Expression Language,表达式语言)是为了使 JSP 写起来更加简单。EL 的灵感
来自于 ECMAScript 和 XPath 表达式语言,
它提供了在 JSP 中简化表达式的方法,使得 JSP
的 代 码 更 加 简 化 。
 例 如 :“ <%=request.getParameter("username")%> ”等价于
“${param.
username}”。

JAVA代审之XSS漏洞

1)out>标签
out>标签用来显示一个表达式的结果,与<%= %>作用相似,它们的区别是,out>标签可以直接通过“.”操作符来访问属性,如下:

<c:out value="${user.getUsername()}"

2)if>标签
if>标签用来判断表达式的值,如果表达式的值为 true,则执行其主体内容:

<c:if test="${user.salary > 2000}"
<p>我的工资为: value="${user.salary}"</p>

3)forEach>标签
forEach>标签的作用是迭代输出标签内部的内容。它既可以进行固定次数的迭代
输出,
也可以依据集合中对象的个数来决定迭代的次数:

<table>
<tr><th>名字</th><th>说明</th><th>图片预览</th></tr>
<c:forEach items="${data}" var="item">
<tr><td>${item.advertName}</td><td>${item.notes}</td><td><img src="${item.defPath}"/></td></tr>
</c:forEach>
</table>
<ul>
<li><a href='?nowPage=${nowPage-1}'>←上一页</a></li>
<c:forEach varStatus="i" begin="1" end="${sumPage}">
<c:choose>
<c:when test="${nowPage==i.count}">
<li class='disabled'>${i.count}</li>
</c:when>
<c:otherwise>
<li class='active'><a href='?nowPage=${i.count}'>${i.count}</a></li>
</c:otherwise>
</c:choose>
</c:forEach>
<li><a href='?nowPage=${nowPage+1}'>下一页→</a></li>
</ul>

3.ModelAndView 类的使用

ModelAndView 类用来存储处理完成后的结果数据,以及显示该数据的视图,其前端
JSP 页面可以使用“${参数}”的方法来获取值:

package com.demo.controller; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.servlet.ModelAndView;

@RequestMapping("mvc"
@Controller
public class TestRequestMMapping { 
 @RequestMapping(value="/getMessage "
 public ModelAndView getMessage(){ 
 ModelAndView modelAndView = new ModelAndView(); 
 modelAndView.setViewName("messgae"); 
 modelAndView.addObject("meggage""Hello World"); 
 return modelAndView; 
 } 
}

4.ModelMap 类的使用
Spring 也提供了 ModelMap 类,
这是 java.util.Map 实现的,可以根据模型属性的具体
类型自动生成模型属性的名称:

Public String testmethod(String someparam,ModelMap model){ 
 //省略方法处理逻辑
 //将数据放置到 ModelMap 类的 model 对象中,第二个参数可以是任何 Java 类型
 Model.addAttribute("key",someparam); 
 return "success"
}

5.Model 类的使用
Model 类是一个接口类,
通过 attribue()添加数据,存储的数据域范围是 requestScope:

Public String index1(Model model){ 
 Model.addAttribute("result","后台返回"); 
 Return "result"
}

常规XSS代码审计

<%=
${ 
<c:out 
<c:if
<c:forEach 
ModelAndView 
ModelMap 
Model 
request.getParameter 
request.setAttribute 
response.getWriter().print() 
response.getWriter().writer()

XSS 漏洞修复

前面已经讲过导致 XSS 漏洞的主要原因是输入可控并且没有经过过滤便直接输出,
因此防御 XSS 漏洞一般有以下几种方法。

(1)编写全局过滤器实现拦截,
并在 web.xml 进行配置。下面将给出一个网上使用较
多的拦截器样例。

WEB.xml

<filter>
      <filter-name>loginFilter</filter-name>
      <filter-class>com.ygj.control.XSSFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>XSSFilter</filter-name>
      <url-pattern>*.jsp</url-pattern>
  </filter-mapping>
  <filter-mapping>
      <filter-name>XSSFilter</filter-name>
      <url-pattern>*.do</url-pattern>
  </filter-mapping>


配置过滤器:

public class XSSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfigthrows ServletException {
    }
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chainthrows
            IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }
}

实现包装类:

import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XSSRequestWrapper extends HttpServletRequestWrapper {
    public XSSRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = stripXSS(values[i]);
        }
        return encodedValues;
    }
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        return stripXSS(value);
    }
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return stripXSS(value);
    }
    private String stripXSS(String value) {
        if (value != null) {
            // NOTE: It's highly recommended to use the ESAPI library and uncomment the followingline to 
            // avoid encoded attacks. 
            // value = ESAPI.encoder().canonicalize(value); 
            // Avoid null characters 
            value = value.replaceAll("""");
            // Avoid anything between script tags 
            Pattern scriptPattern = Pattern.compile("(.*?)", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e-xpression 
            scriptPattern = Pattern.compile("src[rn]*=[rn]*\'(.*?)\'", Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            scriptPattern = Pattern.compile("src[rn]*=[rn]*\"(.*?)\"", Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome tag 
            scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome tag 
            scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE |
                    Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid eval(...) e-xpressions 
            scriptPattern = Pattern.compile("eval\((.*?)\)", Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid e-xpression(...) e-xpressions 
            scriptPattern = Pattern.compile("e-xpression\((.*?)\)", Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid javascript:... e-xpressions 
            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid vbscript:... e-xpressions 
            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid onload= e-xpressions 
            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE |
                    Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
        }
        return value;
    }
}

(2)采用开源安全控制库(OWASP)企业安全应用程序接口(ESAPI)实现,类似的还有谷歌的 xssProtect 等。

// HTML Context 
String html = ESAPI.encoder().encodeForHTML("<script>alert('xss')</script>"); 
// HTML Attribute Context 
String htmlAttr = ESAPI.encoder().encodeForHTMLAttribute("<script>alert('xss')</script>"); 
// Javascript Attribute Context 
String jsAttr = ESAPI.encoder().encodeForJavaScript("<script>alert('xss')</script>");

(3)对所有字符采用 HTML 实体编码。

<%
 String Str = "<script>alert('XSS')</script>"
 Str = Str.replaceAll(""","&quot;"); 
 Str = Str.replaceAll("&","&amp;"); 
 Str = Str.replaceAll("\(","&#40;"); 
 Str = Str.replaceAll("<","&lt;"); 
 Str = Str.replaceAll(">","&gt;"); 
 Str = Str.replaceAll("'","&#39;"); 
 Str = Str.replaceAll("\)","&#41;"); 
 out.println(Str); 
%>

参考很多这里就不注明了,因为我觉得这些知识点没什么可以扩展

原文始发于微信公众号(T3Ysec):JAVA代审之XSS漏洞

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月6日09:53:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JAVA代审之XSS漏洞https://cn-sec.com/archives/4031401.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息