关于面试问到XSS这件事情

关于面试问到XSS这件事情

2021年02月25日

大致看了一遍我以为差不多了,然后面试被问到的时候发现其实差挺多;( 于是补一补总结一下。

XSS

全称Cross-Site Scripting, 译为跨站脚本攻击。 现象是攻击者通过XSS让客户端执行了攻击者的脚本。

脚本执行的后果

如果脚本被执行,那么脚本可以访问到的内容有本地Cookie, Session token(用来调用服务端接口等), 以及通过token拿到其他信息,甚至执行用户其他操作(以当前用户名义)。

脚本执行方式

此处预设客户端将要处理 不可信用户的数据 但是客户端认为它是可信的,比如因为它来自服务端或者其他原因。
Web应用中使用一些容易被攻击的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTMLElement.innerHTML = '不可信用户数据';
HTMLElement.outterHTML = '不可信用户数据';
// 于是你看React的innerHTML使用中出现了danger关键词,是为了提醒开发者

document.write('不可信用户数据');
document.writeln('不可信用户数据');

// 比如你可能允许博客用户自定义自己的空间背景使用自己提供的url
img.src='不可信用户数据';
getElementById('#user-main-container').style.backgroundImage="url('不可信用户数据')";

eval('不可信用户的数据');

// 应该还有其他的

分类

分类的目的是为了更系统地防范XSS

两种分类方式

  1. 存储型反射型DOM Based类型。 分类依据: 数据的持久性。
  2. 服务端XSS(Server XSS)客户端XSS(Client XSS)。 分类依据:出问题的位置。

第一种分类方式因为互有覆盖,分类不够清晰。于是有了第二种分类方式,于是12年之后有了第二种分类方式。

两种分类下的详细定义

存储型:用户输入被服务端存起来了,其他人访问到了这个 不可信用户的数据
反射型:用户输入被服务端即刻返回,返回的数据中有用户输入的部分,于是像是用户的输入再服务端转了一圈变得可信
DOM Based类型不可信用户的数据 并没有通过服务端返回,这类数据被放在了url中,或者是取自DOM中一个input输入框。


服务端XSS
定义:服务端返回的HTTP响应结果中有不可信用户提供的数据

1
Server XSS occurs when untrusted user supplied data is included in an HTTP response generated by the server

此种定义下,就可以有分类方式1中的 存储型反射型

客户端XSS
定义:客户端通过执行一个不安全的JavaScript的函数,使用了不可信用户提供的数据更新DOM

1
Client XSS occurs when untrusted user supplied data is used to update the DOM with an unsafe JavaScript call

于是显然 DOM Based类型客户端XSS 的子集

防范方式

不要在如下所示的位置使用,如果要用请进行各种对应的转义xss-prevention-rules-summary

1
2
3
4
5
6
7
<script>...NEVER PUT UNTRUSTED DATA HERE...</script>
<!--...NEVER PUT UNTRUSTED DATA HERE...-->
<div ...NEVER PUT UNTRUSTED DATA HERE...=test />
<NEVER PUT UNTRUSTED DATA HERE... href="/test" />
<style>
...NEVER PUT UNTRUSTED DATA HERE...
</style>

富文本考虑使用第三方库来做标签和属性等的过滤。

参考资料

Cross Site Scripting (XSS)
Types of XSS
Cross Site Scripting Prevention Cheat Sheet