一般来说,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}”。
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 filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws
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(""",""");
Str = Str.replaceAll("&","&");
Str = Str.replaceAll("\(","(");
Str = Str.replaceAll("<","<");
Str = Str.replaceAll(">",">");
Str = Str.replaceAll("'","'");
Str = Str.replaceAll("\)",")");
out.println(Str);
%>
参考很多这里就不注明了,因为我觉得这些知识点没什么可以扩展
原文始发于微信公众号(T3Ysec):JAVA代审之XSS漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论