什么是 XSS

一、XSS

什么是 XSS

XSS,即 Cross Site Script , 翻译过来就是 跨站脚本攻击;为了和 css 有所区分,因而在安全领域被称为 XSS。

什么是 XSS 攻击

XSS 攻击指的是 攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在别的用户浏览网页的 时候,对用户进行控制或者获取 用户对隐私数据的 这么一种攻击手段。

XSS 攻击的方式 是什么

XSS 攻击可以分为3类:反射型(非持久型)、存储型(持久型)、基于DOM。

XSS攻击需要具备两个条件:需要向web页面注入恶意代码;这些恶意代码能够被浏览器成功的执行。

用户注入的 恶意脚本一般包括 JavaScript 、HTML、Flash。很多种的 XSS 攻击方式,但是共同点是: 将一些 隐私数据像:1、cookie、session 发送给攻击者。 2、将受害者重定向到一个由攻击者控制的网站(俗称钓鱼网站),在受害者的机器上进行一些恶意操作。

反射型(非持久型)的 XSS 攻击

XSS反射型攻击,恶意代码并没有保存在目标网站,而是通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。

直接这么解释还是有点难懂的。下面,我们还是来看个 demo

<a href="http://127.0.0.1:1212/login/<img src=''  onerror='alert(document.cookie)'>" target="_blank" >这是 XSS 的恶意链接</a>

假设某用户在黑客点钓鱼网站上 点击了这个 带有 XSS 攻击的恶意链接。就会跳转到 http://127.0.0.1:1212 这个网站上。刚好这个路径下的 链接是会有一个 发生一个 get 请求。

那么这个时候 <img src='' onerror='alert(document.cookie)'> 这部分的内容就被 当作 请求的 内容发送给了 服务端。如果服务端 为对该 内容进行 XSS 防御,直接返回给 浏览器。

那么这个时候就会出现 XSS 攻击了。<img src='' onerror='alert(document.cookie)'> 这句代码被显示在了 浏览器上,因为 img 标签也具有 跨域属性,直接执行了 onerror 中的 JS 代码。 黑客这个时候就可以 在目标网站上 为所欲为了。

比如这里就是 简单的 alert 了 所有的 cookie。但是,如果我是黑客的话,我肯定会把 用户的 cookie、localStorage、等等重要信息 全部上传到我的服务器,然后进行拿到各类想要的信息。从而获益。

存储型(持久型)的 XSS 攻击

存储型(持久型)的 XSS 攻击 和 反射型 其实也有异曲同工之妙呀。

这么多,我哪里记得住?

别慌,我们慢慢分析一波就都能记住啦~

恶意代码 通过表单提交的方式 被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性,比较常见场景是在博客,论坛、OA、CRM等社交网站上,比如:某CRM系统的客户投诉功能上存在XSS存储型漏洞,黑客提交了恶意攻击代码,当系统管理员查看投诉信息时恶意代码执行,窃取了客户的资料,然而管理员毫不知情,这就是典型的XSS存储型攻击。

我们还是写个 demo 来方便 理解吧

    <div><textarea id="textarea" class="text"></textarea></div>
<button id="btn" class="botton">submit</button>

大概就长这个样子了:

textarea 内则为 带有 xss 的代码,点击提交。直接 xhr 请求到 node 的服务端。

node 服务端 接收到 传入的参数 不做任何 xss 防御 直接保存起来的 js demo

一般是存储 sql 但是这里方便起见 我们就直接存 memory-cache ,代码如下:

router.post("/upload", (ctx, next) => {
let curData = JSON.stringify(ctx.request.body);
cache.put("xss", curData);
ctx.body = `<div>${curData}</div>`;
});

我们请求 一个新的路径来将 memory-cache 的值获取到。 node 端 代码:

router.get("/getName", (ctx, next) => {
let curData = cache.get("xss");
ctx.body = `<div>${JSON.parse(curData)}</div>`;
});

接下来就是访问 http://127.0.0.1:1212/getName

得到 如下 画面:

当然,黑客不会 alert 你的 cookie 信息。 直接 post 到 一个第三方的 服务器上,然后直接模拟浏览器访问,那就简直了。

基于 DOM 的 XSS 攻击

基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。

    const divXss = document.getElementById("xss");
const xssbtn = document.getElementById("xssbtn"); const val = `'' onclick=alert(/xss/)`; xssbtn.addEventListener("click", function() {
divXss.innerHTML = `<a href=${val}>testLink</a>`;
});

当然上面的这个 val 往往是黑客 通过 input 或者 textarea 的 form表单提交引起的

当用户下意识的去点击 这个新增的 dom 的时候,就会出现 如下 场景:

黑客又可以为所欲为了。

二、XSS 的 防御

HttpOnly 防止劫取 Cookie

HttpOnly 最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的Javascript 通过 document.cookie 获取带有 HttpOnly 属性的Cookie。

上文有说到,攻击者可以通过注入恶意脚本获取用户的 Cookie 信息。通常 Cookie 中都包含了用户的登录凭证信息,攻击者在获取到 Cookie 之后,则可以发起 Cookie 劫持攻击。所以,严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 Cookie 劫持攻击。

输入检查

不要相信用户的任何输入。 对于用户的任何输入要进行检查、过滤和转义。建立可信任的字符和 HTML 标签白名单,对于不在白名单之列的字符或者标签进行过滤或编码。

在 XSS 防御中,输入检查一般是检查用户输入的数据中是否包含 <,> 等特殊字符,如果存在,则对特殊字符进行过滤或编码,这种方式也称为 XSS Filter。

而在一些前端框架中,都会有一份 decodingMap, 用于对用户输入所包含的特殊字符或标签进行编码或过滤,如 <,>,script,防止 XSS 攻击:

// vuejs 中的 decodingMap

// 在 vuejs 中,如果输入带 script 标签的内容,会直接过滤掉

const decodingMap = {

'<': '<',

'>': '>',

'"': '"',

'&': '&',

'
': '\n'

}

输出检查

用户的输入会存在问题,服务端的输出也会存在问题。一般来说,除富文本的输出外,在变量输出到 HTML 页面时,可以使用编码或转义的方式来防御 XSS 攻击。

例如利用 sanitize-html 对输出内容进行有规则的过滤之后再输出到页面中。

本 demo 中的 koa 框架其实在输出的时候处理了标签:

这个时候 就会 减少 99% 的 xss 攻击了。是不是发现选择一款好的框架能节省好多的麻烦。

好了,这篇关于 XSS 的文章就介绍到 这里了,别着急 源码会放出来的。

全文的 demo 的源码地址: github源码地址

总结

一旦在DOM解析过程成出现不在预期内的改变,就有可能发生 XSS。

失控 就会出现 BUG。

防御手段 既然 攻防的人都知道了,那么自身代码的严谨程度就决定了整个项目的安度。

突然想起了 PDD ...

GitHub 地址:(欢迎 star 、欢迎推荐 : )

前端 安全 XSS 原理以及防御手段

《前端之路》 之 前端 安全 XSS 原理以及防御手段的更多相关文章

  1. xss原理绕过防御个人总结

    xss原理 xss产生的原因是将恶意的html脚本代码插入web页面,底层原理和sql注入一样,都是因为js和php等都是解释性语言,会将输入的当做命令执行,所以可以注入恶意代码执行我们想要的内容 x ...

  2. 《前端之路》- TypeScript (三) ES5 中实现继承、类以及原理

    目录 一.先讲讲 ES5 中构造函数(类)静态方法和多态 1-1 JS 中原型以及原型链 例子一 1-2 JS 中原型以及原型链中,我们常见的 constructor.prototype.**prot ...

  3. 前端安全(XSS、CSRF防御)

    一.网络安全          OWASP:开放式Web应用程序安全项目(OWASP,Open Web Application Security Project)        OWASP是一个开源的 ...

  4. 《前端之路》之 Javascript 模块化管理的来世今生

    目录 第二章 - 04: Javascript 模块化管理的来世今生 一.什么是模块化开发 1-1.模块化第一阶段 1-2.封装到对象 1-3. 对象的优化 二.模块化管理的发展历程 2-1.Comm ...

  5. 《前端之路》- TypeScript (四) class 中各类属性、方法,抽象类、多态

    目录 一.TypeScript 中的类 二.TypeScript 中类的继承 三.TypeScript 中公共,私有与受保护的修饰符 3-1.属性的 public 3-2.属性的 private 3- ...

  6. jQuery延迟加载(懒加载)插件 – jquery.lazyload.js-Web前端(W3Cways.com) - Web前端学习之路

    Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...

  7. 《前端之路》之二:数据类型转换 && 隐式转换 || 显式转换

    目录 02:数据类型转换 && 隐式转换 || 显式转换 02:数据类型转换 && 隐式转换 || 显式转换 在上一个章节中,我们介绍了 JavaScript 的基本的 ...

  8. 《前端之路》--- 重温 Egg.js

    目录 <前端之路>--- 重温 Egg.js 一.基础功能 > 日志系统包含了 四大层面的 日志对象, 分别是 App Logger.App CoreLogger.Context L ...

  9. 《前端之路》- TypeScript(二) 函数篇

    目录 一.定义函数方法 二.定义函数传参 三.可选传参 四.默认传参 五.传递剩余参数 六.函数重载 七.箭头函数 八.总结 一.定义函数方法 在 es5 中定时函数的方法有 命名函数和函数表达式(匿 ...

随机推荐

  1. 简单而强大的bitset

    简单而强大的bitset 介绍 有些程序需要处理二进制有序集,标准库提供了bitset 类型,事实上,bitset 是一个二进制容器,容器中每一个元素都是一位二进制码,或为 0,或为 1. 基础 bi ...

  2. vue项目 构建 打包 发布 三部曲

    一.vue项目的创建 1.首先第一肯定是要有Node.js及npm这个不多说了2.安装脚手架 此时可以直接浏览-但是现在肯定有很多小白想将他发布到gitHub上并可以浏览,使用vue全家桶制作自己的博 ...

  3. jmeter如何录制App及Web应用

    1.添加一个线程组(Test Plan上右键,添加_Threads_线程组) 2.添加一个HTTP代理服务器(Test Plan上右键,添加_非测试元件_HTTP代理服务器) 3.在HTTP代理服务器 ...

  4. JS 数据类型、赋值、深拷贝和浅拷贝

    js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. null. 一个表明 null 值的特殊关键字. JavaScript 是大小写敏感的,因此 null 与 ...

  5. 一个能够在Asp.Net和Asp.NetCore之间能够互相通讯的Rpc

    一.特性 1.跨平台 2.提供负载均衡算法 3.支持ZK服务协调 4.提供了JSON.BinarySerializer.还有自定义的序列化方式 5.客户端提供Socket连接池,以便于快速交互,防止类 ...

  6. Java线程的中断(Interruption)

    任务和线程的启动很容易.在大多数时候,我们都会让它们运行直到结束,或者让它们自行停止.然而,有时候我们希望提前结束任务或线程,或许是因为用户取消了操作,或者应用程序需要被快速关闭. 要使任务和线程能安 ...

  7. SSM-Spring-11:Spring中使用代理工厂Bean实现aop的四种增强

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 说说那四种增强:前置增强,后置增强,环绕增强,异常增强 那什么是代理工厂bean呢? org.springfr ...

  8. webstorm-快捷键大全

    Webstorm快捷键 Eclipse快捷键 说明 ctrl+shift+N ctrl+shift+R 通过文件名快速查找工程内的文件(必记) ctrl+shift+alt+N ctrl+shift+ ...

  9. navicat for mysql 破解方法

    https://www.cnblogs.com/da19951208/p/6403607.html  破解教程

  10. 说一说js中__proto__和prototype以及原型继承的那些事

    在面试中遇到过,问js如何实现继承,其实最好的方式就是构造函数+原型,今天在讨论中,发现自己以前理解上的一些误区,特地写出来,最近都比较忙,等手上的项目做完,可以来做个总结. 先说我以前没有认识到位的 ...