随笔 - 27, 文章 - 0, 评论 - 0, 阅读 - 988
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

安全测试--常见漏洞--XSS

Posted on   砂锅米粥  阅读(107)  评论(0编辑  收藏  举报

漏洞简介

Cross-Site Scripting(为了与CSS区别,安全领域叫做XSS)攻击是注入的一种,主要是将恶意脚本注入到可信站点的HTML页面等网页文件中,当攻击者将带有恶意脚本的网页链接发送给用户,用户打开链接,浏览器会认为恶意脚本来自可信站点而执行

举个例子

 

@app.route("/")
def index():
    param = request.args.get("param", "")
    response = make_response("<p>Hello {}</p>".format(param))
    response.set_cookie("key", "value", httponly=False)  # 关闭框架自带的httponly=true
    response.headers["X-XSS-Protection"] = 0  # Chrome本身的XSS防御关闭
    return response

构造一个恶意URL http://test.com/param=<script>alert(document.cookie)</script>

浏览器打开后可以看到页面的反馈,弹出一个弹框,带有设置的 key: value 的Cookie

实际攻击可以将上述代码逻辑修改为,通过Ajax把Cookie信息发送到攻击者服务器,攻击者就可以盗取用户身份访问站点

XSS攻击发生在

  • 数据通过不可信源进入Web应用程序,最常见的是Web请求
  • 数据被包含在动态内容中,该动态内容被发送到Web用户而不被验证为恶意内容,发送到Web浏览器的恶意内容通常采用JS的一种形式,但也可以包括HTML、Flash或者浏览器可执行的任何其他类型代码

XSS的攻击效果

  • 基于XSS的攻击种类几乎是无限的
  • 它们通常包括向攻击者发送诸如Cookie或其他会话信息之类的私有数据,将受害者重定向到攻击者控制的Web内容,或者在用户的机器上执行其他恶意操作
  • 因为客户端JS等脚本语言的灵活性,XSS攻击可以和其他攻击方式在合适场景中相结合,造成更大的破坏

XSS的类型

反射型XSS

反射型XSS是用户输入直接作为响应的一部分作为服务器输出,如用户提交的表单、URL作为错误信息、搜索结果返回给用户,攻击者构造恶意的URL,Web表单发送给用户,用户点击就会触发

比如上面漏洞介绍里举的例子就是反射型XSS

存储型XSS

存储型XSS会把用户输入的数据“存储”到服务端,往往是数据库,往往具有更强的稳定性和破坏性,产生这种漏洞的页面功能往往是 往往是论坛消息、访问者日志、评论字段等

举个例子

我们在类似QQ空间的Web系统中提交文章和评论,会被存储在服务器数据库中,我们可以根据文章ID查询到文章内容

文章的显示页面逻辑往往如下

@app.route("/")
def index():
    post_id = request.args.get("id", "")
    post = db.query(post_id=post_id).first()
    response = make_response("<textview> {}<textview>".format(post.content))
    response.set_cookie("key", "value", httponly=False)  # 关闭框架自带的httponly=true
    response.headers["X-XSS-Protection"] = 0  # Chrome本身的XSS防御关闭
    return response

可以看到逻辑和上面反射型XSS基本是一样的,当用户将 <script>alert(document.cookie)</scirpt> 一类的攻击脚本写入文章,其他用户访问时便会触发XSS

存储型XSS由于不用在URL中构造恶意脚本也更容易对用户进行钓鱼,不易被识别

DOM型XSS

以上两种XSS是根据恶意脚本是否能持久化(保存在服务端)进行划分的,DOM Based XSS从效果上来说也是反射型XSS,但因为成因特别,就单独作为一类

我们把修改页面DOM节点形成的XSS,称为DOM Based XSS

比如前端页面的代码为

<p>Select your language:</p>
<select>
<script>
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");
document.write("<OPTION value=2>English</OPTION>");
</script>
</select>

普通情况下的正常请求是 http://www.some.site/page.html?default=French

恶意请求 http://www.some.site/page.html?default=<script>alert(document.cookie)</script>

我们发现上面这样的请求和反射型XSS差不多,那么为什么DOM型XSS要单独分为一类呢

因为在前后端分离的页面中,SPA等模式中,这些请求会只在前端消化,不会传送到后端

另外一种情况,还是上面的页面,假如我们的服务器对XSS有着非常好的过滤和编码方式,请求从服务器返回时类似 <script>,document.cookie,alert 这些字段都去掉了,那有什么办法再生成XSS攻击呢

我们把URL变成 http://www.some.site/page.html#default=<script>alert(document.cookie)</script> ,我们可以发现此时攻击仍然能够生效

URL有个特点, # 被称为锚点,用于定位页面位置,#符号后的内容不会传输到服务器

再进一步思考,反射型和存储型XSS中,参数值为恶意脚本,服务器端没有经过检查和过滤将恶意脚本拼接到了HTML页面中,浏览器加载页面执行脚本造成了XSS攻击,而通过URL锚点触发的XSS没有经过服务器,浏览器充当服务器角色拼接脚本到HTML页面中

也就是说我们多把后台服务改变网页代码造成的XSS叫做反射型XSS,而网页本身的JS改变的叫做DOM型XSS

笔者认为在B/S构架中,越来越灵活的Web使得浏览器和JS充当了一个客户端里的小型服务器,对用户的部分响应不需要再经过真正服务端的处理,预置在页面JS脚本中的一部分函数和功能直接处理了用户输入输出,或者对服务器的返回进行再处理,因此DOM型XSS也是针对浏览器和JS这个小型服务器的攻击,才被单独作为一类

除了上面例子中href.location获取参数外,还要注意一些请求参数在服务器端经过一定的编码和过滤,但仍然可以通过DOM的改变对这些参数再一次进行处理,所以要注意防御XSS是防御最后浏览器显示的页面,而对DOM改变的操作相当于返回给用户的页面不用从真正服务端给出,而是浏览器和JS给出的

XSS的利用方式

基本上XSS能够做到事就是JS一类的脚本能做到的事,这里举一些XSS的利用方式,但不具体说明

  • 盗取用户Cookie(登录态)
  • 构造GET、POST等HTTP方法模拟网站逻辑以劫持用户身份执行(类似CSRF)
  • 盗取页面数据,如一下用户敏感信息
  • 识别用户浏览器
  • 识别用户访问历史
  • XSS蠕虫

修复方式

编码转换

这是防御XSS中最重要最有效的一步,服务端对要输出给用户的Web文件内容做以下编码转换(实体编码),同理,如果JS改变了DOM,也要在JS中对数据内容进行以下编码,对于用户的输入输出更要重点处理



& --> &amp;
< --> &lt;
> --> &gt;
" --> &quot;
/ --> &#x2F;
' --> &#x27;     单引号也有转换成&apos;的情况,但是不推荐,因为这种转换不在HTML的规范中,而是在XML和XHTML的规范中

随着前端技术的发展,使用类似Angular JSVUE JS的框架,本身自带编码转换,了解相关模块的配置之后使用

建议是在输出的时候进行验证和过滤,常见的情况如下

注入点

示例

方法

HTML元素注入

<div>content</div>

node.textContent=content

HTML原属属性

<input value="content">

element.setAttribute('input', content)

element['input']=content

URL请求参数

http://a.com?a=content

window.encodeURLComponenbt(content)

CSS值

color: content

element.style.color=content

JavaScript

var name='content'

不适合编码来保护,没有内置编码方法提供保护,可以通过URL编码等但是容易对应用逻辑产生影响



使用Cookie的httponly标识

为Cookie字段带上httponly的标识,可以防止JS读取Cookie信息,因此可以有效防止XSS攻击中盗取用户Cookie的能力
但是这种方式不是防御了XSS漏洞,只是减少了XSS漏洞造成的损失,但依旧十分有效,前端页面不需要读取Cookie的话尽量为每个Cookie配置这个标识

使用X-XSS-Protection头部进行防御

浏览器本身内置了XSS的防御审计工具,可以通过X-XSS-Protection进行配置,但是浏览器的防御攻击也是人写的代码,本身具有安全隐患

X-XSS-Protection的安全隐患

建议在看明白上文后使用,建议按需求使用X-XSS-Protection: 1; mode=blockX-XSS-Protection: 0两种配置,但其实浏览器本身也在升级,未来可能会更加好用

XSS过滤

存在一些情况,比如富文本,不能使用HTML实体编码的方式进行XSS防御,因为富文本中需要用到HTML标签来显示,在了解需求的情况下使用白名单进行过滤,因为XSS攻击的灵活只推荐使用白名单

设置白名单需要对XSS的可以利用的HTML标签和位置有一定了解,参考OWASP的开源项目anti-samy

不使用Flash

Flash已淘汰,不推荐使用

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示