XSS全称是Cross Site Scripting(为了和CSS进行区分,就叫XSS)即跨站脚本,当目标网站目标用户浏览器渲染HTML文档的过程中,出现了不被预期的脚本指令并执行时,XSS就发生了
XSS有三类:反射型XSS(非持久型)、存储型XSS(持久型)和DOM XSS
发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以称反射型XSS。 一个简单的例子:
<?php
echo $_GET['x'];
?>
如果输入x的值没有经过任何过滤直接输出,假设提交链接为:
http://www.foo.com/xss/reflect.php?x=<script>alert(1)</script>
则alert()函数会在浏览器访问时触发
存储型XSS和反射型XSS的差别仅在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求目标页面时不用再提交XSS代码。最典型的例子就是留言板XSS,用户提交一条包含XSS代码的留言存储到数据库,目标用户查看留言板时,那些留言就会从数据库中加载出来并显示,于是出发了XSS攻击
DOM XSS和反射型XSS、存储型XSS的区别在于DOM XSS代码并不需要服务器参与,出发XSS靠的是浏览器的DOM解析,完全是客户端的事情
www.xss.com/domxss.html 代码如下:
<script>
eval(localtion.hash.substr(1));
</script>
触发方式为:www.xss.com/domxss.html#alert(1) 这个URL#后的内容是不会发送到服务器端的,仅仅在客户端被接收并执行,常见的输入点有:
document.URL
document.URLUnencoded
document.localtion
document.referrer
window.location
window.name
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'xss_test.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<%
String str = request.getParameter("name");
out.print(str);
%>
</body>
</html>
首先访问:http://localhost:8080/jsp/user/xss_test.jsp?name=小明
接着我们试着加载一个js脚本看看,访问:http://localhost:8080/jsp/user/xss_test.jsp?name=<script>alert("XSS")</script>
那么是不是可以改变跳转后的地址?访问:http://localhost:8080/jsp/user/xss_test.jsp?name=<script>location.href='http://www.baidu.com'</script>