当前位置: 首页 > news >正文

33 _ 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

通过上篇文章的介绍,我们知道了同源策略可以隔离各个站点之间的DOM交互、页面数据和网络通信,虽然严格的同源策略会带来更多的安全,但是也束缚了Web。这就需要在安全和自由之间找到一个平衡点,所以我们默认页面中可以引用任意第三方资源,然后又引入CSP策略来加以限制;默认XMLHttpRequest和Fetch不能跨站请求资源,然后又通过CORS策略来支持其跨域。

不过支持页面中的第三方资源引用和CORS也带来了很多安全问题,其中最典型的就是XSS攻击。

什么是XSS攻击

XSS全称是Cross Site Scripting,为了与“CSS”区分开来,故简称XSS,翻译过来就是“跨站脚本”。XSS攻击是指黑客往HTML文件中或者DOM中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。

最开始的时候,这种攻击是通过跨域来实现的,所以叫“跨域脚本”。但是发展到现在,往HTML文件中注入恶意代码的方式越来越多了,所以是否跨域注入脚本已经不是唯一的注入手段了,但是XSS这个名字却一直保留至今。

当页面被注入了恶意JavaScript脚本时,浏览器无法区分这些脚本是被恶意注入的还是正常的页面内容,所以恶意注入JavaScript脚本也拥有所有的脚本权限。下面我们就来看看,如果页面被注入了恶意JavaScript脚本,恶意脚本都能做哪些事情。

  • 可以窃取Cookie信息。恶意JavaScript可以通过“document.cookie”获取Cookie信息,然后通过XMLHttpRequest或者Fetch加上CORS功能将数据发送给恶意服务器;恶意服务器拿到用户的Cookie信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。
  • 可以监听用户行为。恶意JavaScript可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。
  • 可以通过修改DOM伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。
  • 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验。

除了以上几种情况外,恶意脚本还能做很多其他的事情,这里就不一一介绍了。总之,如果让页面插入了恶意脚本,那么就相当于把我们页面的隐私数据和行为完全暴露给黑客了。

恶意脚本是怎么注入的

现在我们知道了页面中被注入恶意的JavaScript脚本是一件非常危险的事情,所以网站开发者会尽可能地避免页面中被注入恶意脚本。要想避免站点被注入恶意脚本,就要知道有哪些常见的注入方式。通常情况下,主要有存储型XSS攻击、反射型XSS攻击基于DOM的XSS攻击三种方式来注入恶意脚本。

1. 存储型XSS攻击

我们先来看看存储型XSS攻击是怎么向HTML文件中注入恶意脚本的,你可以参考下图:

存储型XSS攻击

通过上图,我们可以看出存储型XSS攻击大致需要经过如下步骤:

  • 首先黑客利用站点漏洞将一段恶意JavaScript代码提交到网站的数据库中;
  • 然后用户向网站请求包含了恶意JavaScript脚本的页面;
  • 当用户浏览该页面的时候,恶意脚本就会将用户的Cookie信息等数据上传到服务器。

下面我们来看个例子,2015年喜马拉雅就被曝出了存储型XSS漏洞。起因是在用户设置专辑名称时,服务器对关键字过滤不严格,比如可以将专辑名称设置为一段JavaScript,如下图所示:

黑客将恶意代码存储到漏洞服务器上

当黑客将专辑名称设置为一段JavaScript代码并提交时,喜马拉雅的服务器会保存该段JavaScript代码到数据库中。然后当用户打开黑客设置的专辑时,这段代码就会在用户的页面里执行(如下图),这样就可以获取用户的Cookie等数据信息。

用户打开了含有恶意脚本的页面

当用户打开黑客设置的专辑页面时,服务器也会将这段恶意JavaScript代码返回给用户,因此这段恶意脚本就在用户的页面中执行了。

恶意脚本可以通过XMLHttpRequest或者Fetch将用户的Cookie数据上传到黑客的服务器,如下图所示:

将Cookie等数据上传到黑客服务器

黑客拿到了用户Cookie信息之后,就可以利用Cookie信息在其他机器上登录该用户的账号(如下图),并利用用户账号进行一些恶意操作。

黑客利用Cookie信息登录用户账户

以上就是存储型XSS攻击的一个典型案例,这是乌云网在2015年曝出来的,虽然乌云网由于某些原因被关停了,但是你依然可以通过这个站点来查看乌云网的一些备份信息。

2. 反射型XSS攻击

在一个反射型XSS攻击过程中,恶意JavaScript脚本属于用户发送给网站请求中的一部分,随后网站又把恶意JavaScript脚本返回给用户。当恶意JavaScript脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。

这样讲有点抽象,下面我们结合一个简单的Node服务程序来看看什么是反射型XSS。首先我们使用Node来搭建一个简单的页面环境,搭建好的服务代码如下所示:

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get(‘/’, function(req, res, next) {
res.render(‘index’, { title: ‘Express’,xss:req.query.xss });
});

module.exports = router;

<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel=‘stylesheet’ href=‘/stylesheets/style.css’ />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<div>
<%- xss %>
</div>
</body>
</html>

上面这两段代码,第一段是路由,第二段是视图,作用是将URL中xss参数的内容显示在页面。我们可以在本地演示下,比如打开http://localhost:3000/?xss=123这个链接,这样在页面中展示就是“123”了(如下图),是正常的,没有问题的。

正常打开页面

但当打开http://localhost:3000/?xss=<script>alert(‘你被xss攻击了’)</script>这段URL时,其结果如下图所示:

反射型XSS攻击

通过这个操作,我们会发现用户将一段含有恶意代码的请求提交给Web服务器,Web服务器接收到请求时,又将恶意代码反射给了浏览器端,这就是反射型XSS攻击。在现实生活中,黑客经常会通过QQ群或者邮件等渠道诱导用户去点击这些恶意链接,所以对于一些链接我们一定要慎之又慎。

另外需要注意的是,Web服务器不会存储反射型XSS攻击的恶意脚本,这是和存储型XSS攻击不同的地方

3. 基于DOM的XSS攻击

基于DOM的XSS攻击是不牵涉到页面Web服务器的。具体来讲,黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面传输过程中修改HTML页面的内容,这种劫持类型很多,有通过WiFi路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点是在Web资源传输过程或者在用户使用页面的过程中修改Web页面的数据。

如何阻止XSS攻击

我们知道存储型XSS攻击和反射型XSS攻击都是需要经过Web服务器来处理的,因此可以认为这两种类型的漏洞是服务端的安全漏洞。而基于DOM的XSS攻击全部都是在浏览器端完成的,因此基于DOM的XSS攻击是属于前端的安全漏洞。

但无论是何种类型的XSS攻击,它们都有一个共同点,那就是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上。

所以要阻止XSS攻击,我们可以通过阻止恶意JavaScript脚本的注入和恶意消息的发送来实现。

接下来我们就来看看一些常用的阻止XSS攻击的策略。

1. 服务器对输入脚本进行过滤或转码

不管是反射型还是存储型XSS攻击,我们都可以在服务器端将一些关键的字符进行转码,比如最典型的:

code:<script>alert(‘你被xss攻击了’)</script>

这段代码过滤后,只留下了:

code:

这样,当用户再次请求该页面时,由于<script>标签的内容都被过滤了,所以这段脚本在客户端是不可能被执行的。

除了过滤之外,服务器还可以对这些内容进行转码,还是上面那段代码,经过转码之后,效果如下所示:

code:&lt;script&gt;alert(&#39;你被xss攻击了&#39;)&lt;/script&gt;

经过转码之后的内容,如<script>标签被转换为&lt;script&gt;,因此即使这段脚本返回给页面,页面也不会执行这段脚本。

2. 充分利用CSP

虽然在服务器端执行过滤或者转码可以阻止 XSS 攻击的发生,但完全依靠服务器端依然是不够的,我们还需要把CSP等策略充分地利用起来,以降低 XSS攻击带来的风险和后果。

实施严格的CSP可以有效地防范XSS攻击,具体来讲CSP有如下几个功能:

    • 限制加载其他域下的资源文件,这样即使黑客插入了一个JavaScript文件,这个JavaScript文件也是无法被加载的;
    • 禁止向第三方域提交数据,这样用户数据也不会外泄;
    • 禁止执行内联脚本和未授权的脚本;
    • 还提供了上报机制,这样可以帮助我们尽快发现有哪些XSS攻击,以便尽快修复问题。
    • 因此,利用好CSP能够有效降低XSS攻击的概率。

      3. 使用HttpOnly属性

      由于很多XSS攻击都是来盗用Cookie的,因此还可以通过使用HttpOnly属性来保护我们Cookie的安全。

      通常服务器可以将某些Cookie设置为HttpOnly标志,HttpOnly是服务器通过HTTP响应头来设置的,下面是打开Google时,HTTP响应头中的一段:

      set-cookie: NID=189=M8q2FtWbsR8RlcldPVt7qkrqR38LmFY9jUxkKo3-4Bi6Qu_ocNOat7nkYZUTzolHjFnwBw0izgsATSI7TZyiiiaV94qGh-BzEYsNVa7TZmjAYTxYTOM9L_-0CN9ipL6cXi8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly
      

      我们可以看到,set-cookie属性值最后使用了HttpOnly来标记该Cookie。顾名思义,使用HttpOnly标记的Cookie只能使用在HTTP请求过程中,所以无法通过JavaScript来读取这段Cookie。我们还可以通过Chrome开发者工具来查看哪些Cookie被标记了HttpOnly,如下图:

      HttpOnly演示

      从图中可以看出,NID这个Cookie的HttpOlny属性是被勾选上的,所以NID的内容是无法通过document.cookie是来读取的。

      由于JavaScript无法读取设置了HttpOnly的Cookie数据,所以即使页面被注入了恶意JavaScript脚本,也是无法获取到设置了HttpOnly的数据。因此一些比较重要的数据我们建议设置HttpOnly标志。

      总结

      好了,今天我们就介绍到这里,下面我来总结下本文的主要内容。

      XSS攻击就是黑客往页面中注入恶意脚本,然后将页面的一些重要数据上传到恶意服务器。常见的三种XSS攻击模式是存储型XSS攻击、反射型XSS攻击和基于DOM的XSS攻击。

      这三种攻击方式的共同点是都需要往用户的页面中注入恶意脚本,然后再通过恶意脚本将用户数据上传到黑客的恶意服务器上。而三者的不同点在于注入的方式不一样,有通过服务器漏洞来进行注入的,还有在客户端直接注入的。

      针对这些XSS攻击,主要有三种防范策略,第一种是通过服务器对输入的内容进行过滤或者转码,第二种是充分利用好CSP,第三种是使用HttpOnly来保护重要的Cookie信息。

      当然除了以上策略之外,我们还可以通过添加验证码防止脚本冒充用户提交危险操作。而对于一些不受信任的输入,还可以限制其输入长度,这样可以增大XSS攻击的难度。

      思考时间

      今天留给你的思考题是:你认为前端开发者对XSS攻击应该负多大责任?

      欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友。

    相关文章:

    33 _ 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

    通过上篇文章的介绍&#xff0c;我们知道了同源策略可以隔离各个站点之间的DOM交互、页面数据和网络通信&#xff0c;虽然严格的同源策略会带来更多的安全&#xff0c;但是也束缚了Web。这就需要在安全和自由之间找到一个平衡点&#xff0c;所以我们默认页面中可以引用任意第三…...

    C++入门小结

    C命名空间总结 C 中的命名空间&#xff08;Namespace&#xff09;是一种组织代码的方式&#xff0c;用于避免全局命名冲突。在同一个命名空间中&#xff0c;可以有相同名称的变量、函数和类&#xff0c;但它们彼此互不影响。下面是对 C 命名空间的一些总结&#xff1a; 定义命…...

    Java 开发实例:Spring Boot+AOP+注解+Redis防重复提交(防抖)

    文章目录 1. 环境准备2. 引入依赖3. 配置Redis4. 创建防重复提交注解5. 实现AOP切面6. 创建示例Controller7. 测试8. 进一步优化8.1 自定义异常处理8.2 提升Redis的健壮性 9. 总结 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨…...

    使用difflib实现文件差异比较用html显示

    1.默认方式&#xff0c;其中加入文本过长&#xff0c;需要换行&#xff0c;因此做 contenthtml_output.replace(</style>,table.diff td {word-wrap: break-word;white-space: pre-wrap;max-width: 100%;}</style>)&#xff0c;添加换行操作 ps&#xff1a;当前te…...

    【文末附gpt升级秘笈】AI热潮降温与AGI场景普及的局限性

    AI热潮降温与AGI场景普及的局限性 摘要&#xff1a; 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI热一度席卷全球&#xff0c;引发了广泛的关注和讨论。然而&#xff0c;近期一些学者和行业专家对AI的发展前景提出了质疑&#xff0c;认为AI热潮将逐渐…...

    Vue待学习

    整个渲染过程了解 Vue实例&#xff1f;Vue模板&#xff1f;渲染函数render&#xff08;&#xff09;&#xff1f;虚拟DOM VNode?模板编译器&#xff1f;diff算法 CSS相关 CSS高级学习&#xff1f;过渡&#xff1f; 待熟悉掌握 Vue-router?VueX&#xff1f;Vue-Cli、Webpack和…...

    TOP150-LC88

    /*给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。注意&#xff1a;最终&#xff0c;合并后数组不…...

    使用Python和TCN进行时间序列预测:一个完整的实战示例

    使用Python和TCN进行时间序列预测&#xff1a;一个完整的实战示例 时间卷积网络&#xff08;TCN&#xff09;已被证明在处理序列数据方面表现出色&#xff0c;尤其是在需要捕获长期依赖关系的任务中。在本文中&#xff0c;我们将通过一个简单的例子&#xff0c;展示如何使用Py…...

    如何用R语言ggplot2画高水平期刊散点图

    文章目录 前言一、数据集二、ggplot2画图1、全部代码2、细节拆分1&#xff09;导包2&#xff09;创建图形对象3&#xff09;主题设置4&#xff09;轴设置5&#xff09;图例设置6&#xff09;散点颜色7&#xff09;保存图片 前言 一、数据集 数据下载链接见文章顶部 处理前的数据…...

    Python基于 Jupyter Notebook 的图形可视化工具库之ipysigma使用详解

    概要 在数据科学和网络分析中,图(Graph)结构是一种常用的数据结构,用于表示实体及其关系。为了方便图数据的可视化和交互操作,ipysigma 提供了一个基于 Jupyter Notebook 的图形可视化工具。通过 ipysigma,用户可以在 Jupyter Notebook 中创建、编辑和展示图结构,方便进…...

    四叉树和KD树

    1. 简介 四叉树和KD树都是用于空间数据索引和检索的树状数据结构。它们通过将空间递归地划分为更小的区域&#xff0c;并存储每个区域内的点&#xff0c;来实现快速搜索和范围查询。 2. 四叉树 2.1 定义 四叉树是一种树状数据结构&#xff0c;它将二维空间递归地划分为四个…...

    C语言中结构体使用.与->访问成员变量的区别

    文章目录 前言点运算符&#xff08;.&#xff09;箭头运算符&#xff08;->&#xff09;总结 前言 在C语言中&#xff0c;. 和 -> 都是用来访问结构体成员的运算符&#xff0c;但它们的使用场景和含义有所不同。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面…...

    计算机二级Access选择题考点

    在Access中&#xff0c;若要使用一个字段保存多个图像、图表、文档等文件&#xff0c;应该设置的数据类型是附件。在“销售表"中有字段:单价、数量、折扣和金额。其中&#xff0c;金额单价x数量x折扣&#xff0c;在建表时应将字段"金额"的数据类型定义为计算。若…...

    人工智能历史与现状

    1 人工智能历史与现状 1.1 人工智能的概念和起源 1.1.1 人工智能的概念 人工智能 (Artificial Intelligence ,AI)是一门研究如何使计算机 能够模拟人类智能行为的科学和技术,目标在于开发能够感知、理解、 学习、推理、决策和解决问题的智能机器。人工智能的概念主要包含 以…...

    【git使用一】windows下git下载、安装和卸载

    目录 &#xff08;1&#xff09;下载安装包 &#xff08;2&#xff09;安装git &#xff08;3&#xff09;安装验证 &#xff08;4&#xff09;卸载git &#xff08;1&#xff09;下载安装包 官网下载地址&#xff1a;Git 国内镜像下载地址&#xff1a;CNPM Binaries Mir…...

    JVM 类加载器的工作原理

    JVM 类加载器的工作原理 类加载器&#xff08;ClassLoader&#xff09;是一个用于加载类文件的子系统&#xff0c;负责将字节码文件&#xff08;.class 文件&#xff09;加载到 JVM 中。Java 类加载器允许 Java 应用程序在运行时动态地加载、链接和初始化类。 2. 类加载器的工…...

    ARM Cortex-M4 CPU指令大全:作用、原理与实例

    引言 在计算机系统中&#xff0c;CPU&#xff08;中央处理器&#xff09;是执行各种指令的核心部件。ARM Cortex-M4是广泛应用于嵌入式系统中的一款处理器&#xff0c;其指令集架构&#xff08;ISA&#xff09;基于ARMv7-M。本文将介绍ARM Cortex-M4处理器中的常见指令&#x…...

    Mysql学习(九)——存储引擎

    提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 七、存储引擎7.1 MySQL体系结构7.2 存储引擎简介7.3 存储引擎特点7.4 存储引擎选择7.5 总结 七、存储引擎 7.1 MySQL体系结构 连接层&#xff1a;最上层是一些客户…...

    TFT屏幕波形显示

    REVIEW 关于TFT显示屏&#xff0c;之前已经做过彩条显示&#xff1a; TFT显示屏驱动_tft驱动-CSDN博客 关于ROM IP核&#xff0c;以及coe文件生成&#xff1a; FPGA寄存器 Vivado IP核_fpga寄存器资源-CSDN博客 1. TFT屏幕ROM显示正弦波 ①生成coe文件 %% sin-cos wave dat…...

    服务器无法远程桌面连接不上的问题排查与解决方案

    一、问题概述 当尝试使用远程桌面协议&#xff08;RDP&#xff09;连接至服务器时&#xff0c;如果连接失败&#xff0c;这通常意味着存在一些配置问题、网络问题或服务器本身的问题。此类问题对于管理员而言&#xff0c;需要系统地进行排查和解决。 二、排查步骤 1. 检查网…...

    JAVA面试题整理——内存溢出与内存泄露的区别与联系

    内存溢出与内存泄露的区别与联系 在前面jvm学习整理的时候其实用过一个简单的例子了解过内存溢出&#xff0c;在jvm内存模型章节下&#xff0c;大家有兴趣的可以去看看&#xff1a;JVM初学 GC_knowwait的博客-CSDN博客 内存溢出 内存溢出&#xff08;out of memory&#xff09…...

    L50--- 104. 二叉树的最大深度(深搜)---Java版

    1.题目描述 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 2.思路 这个二叉树的结构如下&#xff1a; 根节点 1 左子节点 2 右子节点 3 左子节点 4 计算过程 从根节点 1 开始计算&#xff1a; 计算左子树的最大深度&#xff1a; 根节点 2&#xf…...

    Linux 中 “ 磁盘、进程和内存 ” 的管理

    在linux虚拟机中也有磁盘、进程、内存的存在。第一步了解一下磁盘 一、磁盘管理 &#xff08;1.1&#xff09;磁盘了解 track&#xff08; 磁道 &#xff09; &#xff1a;就是磁盘上的同心圆&#xff0c;从外向里&#xff0c;依次排序1号&#xff0c;2号磁盘........等等。…...

    test_pipeline

    test_pipeline 是一个测试管道&#xff08;test pipeline&#xff09;的定义。 在计算机视觉任务中&#xff0c;通常需要对输入图像进行一系列的预处理操作&#xff0c;以便将其适配到模型的输入要求或提高模型的性能。测试管道就是用于定义这些预处理操作的一系列步骤。 在给…...

    使用甲骨文云arm服务器安装宝塔时nginx无法卸载

    使用甲骨文云arm服务器安装宝塔 其他环境都能安装上 唯独nginx安装完不运行 卸载了几次以后还无法卸载了. 修复 重启都不行. 差点就重建主机了. 最后靠下面的命令 就卸载掉了 然后重装就把nginx安装好了 mv /www/server/nginx/sbin/nginx /tmp/nginx_back mv /etc/in…...

    C++青少年简明教程:C++的指针入门

    C青少年简明教程&#xff1a;C的指针入门 说到指针&#xff0c;就不可能脱离开内存。了解C的指针对于初学者来说可能有些复杂&#xff0c;我们可以试着以一种简单、形象且易于理解的方式来解释&#xff1a; 首先&#xff0c;我们可以将计算机内存想象成一个巨大的有许多格子的…...

    Apache Doris 基础 -- 数据表设计(分层存储)

    1、应用场景 未来一个重要的用例是类似于ES日志存储&#xff0c;其中日志场景中的数据是根据日期分割的。许多数据都是查询不频繁的冷数据&#xff0c;因此需要降低此类数据的存储成本。考虑到节约成本: 来自不同厂商的常规云磁盘的定价比对象存储更昂贵。Doris 集群实际在线…...

    使用Spring Boot设计一套BI系统

    商业智能&#xff08;Business Intelligence&#xff0c;简称BI&#xff09;系统是一种将数据转化为可操作信息&#xff0c;帮助企业进行决策支持的技术与工具的集合。随着大数据时代的到来&#xff0c;BI系统在企业中的应用变得越来越广泛。本文旨在探讨如何使用Spring Boot框…...

    2024.6.12总结

    今天是排毕业照的日子&#xff0c;拍照的时候并没有太过兴奋。后来受到主管说明天就能签offer了&#xff0c;这才喜极而泣。 自从得知自己面试通过后&#xff0c;我是非常高兴&#xff0c;开始幻想着今后的生活。可是&#xff0c;后面在等offer的过程中&#xff0c;我是无比的…...

    1027 - 求任意三位数各个数位上数字的和

    问题描述 对于一个任意的三位自然数 x &#xff0c;编程计算其各个数位上的数字之和 S 。 输入 输入一行&#xff0c;只有一个整数 x(100≤x≤999) 。 输出 输出只有一行&#xff0c;包括 1 个整数。 样例 输入 123 输出 6 以下是C实现的代码&#xff1a; 代码1 #…...