XSS学习笔记

一、XSS 简介

XSS(Cross-Site Script,跨站脚本攻击)

攻击方式如下图所示:


XSS攻击

XSS 攻击根据不同的注入和攻击形式,通常划分为以下三种类型:

(1)反射型(非持久型)XSS
  • 示意图:
    反射型(非持久型)XSS攻击示意图
  • 特点:
    依赖于服务器,服务端直接使用恶意脚本并返回结果页
    其攻击方式往往是通过诱导用户去点击一些带有恶意脚本参数的 URL而发起的;
    反射型 XSS 其实就是服务器对恶意的用户输入没有进行安全防范处理就直接使用到响应页面中,然后反射响应内容给用户,从而导致恶意代码在浏览器执行的一种 XSS 漏洞;
    事实上由于反射型 XSS 因为 url 特征所以很容易被防御。很多浏览器如 Chrome 都内置了 相应的 XSS Filter(过滤器),可以防止大部分反射型XSS攻击。
(2)存储型(持久型)XSS
  • 示意图:
    存储型(持久型)XSS攻击示意图
  • 特点:
    依赖于服务器,服务端存储恶意脚本并返回
    存储型 XSS 并不需要用户点击链接才能触发;
    持久型 XSS 其实就是对恶意的用户输入没有进行检测处理就保存在服务端的文件或者数据库中,并且取出恶意的数据时也没有做相关安全处理就返回响应,导致了存储的恶意脚本数据在浏览器中执行的一种 XSS 漏洞;
    无论是反射型 XSS 还是存储型 XSS,其本质都是 XSS 攻击。 XSS 攻击的本质就是由于浏览器执行攻击者插入的恶意的脚步数据所致。
(3)DOM-Basedx型 XSS
  • 示意图:
    DOM-Basedx型 XSS攻击示意图
  • 特点:
    不依赖于服务器,数据来源于客户端
    从效果来看 ,DOM-Based 型 XSS 也是需要诱导用户去打开相应恶意链接才能发送的 XSS 攻击;
    DOM-Based 型 XSS 是由于客户端 JavaScript 脚本修改页面 DOM 结构时(修改文本、重绘、重排)引起浏览器 DOM 解析所造成的一种漏洞攻击;
    如果页面 JavaScript 脚本不存在着漏洞的话,则不会发送 DOM-Based 型 XSS 攻击。一般常触发的场景为:innerHTML,outerHTML,document.write等。

二、XSS payload

  • 能够实现XSS攻击的恶意脚本就是XSS payload
  • 主要类型如下:
    窃取用户的cookie(可通过document.cookie获取。例如:cookie是网站中表示用户登录态的重要信息,如果窃取cookie,便能模仿用户的登录态。)
    识别用户浏览器(可通过navigator.userAgent获取。根据不同浏览器使用不同的攻击方式)
    伪造请求(通过Ajax<img><a>srcform表单等发起get/post请求,从而实现XSS攻击)
    XSS钓鱼(XSS payload + 钓鱼网站。例如,在评论区输入<a href="www.fish.com">王者荣耀周年活动</a>,诱使用户点击后跳转到钓鱼网站输入用户名和密码,以此来盗取帐号)

三、XSS 防御

1. 给cookie设置httpOnly

  • 设置 Cookie 的 httpOnly 属性时,会致使客户端脚本(即JavaScript)无法访问cookie的信息(例如在控制台打印document.cookie无法获取到信息),只有与服务端交互的时候,http请求头才会带上该cookie的信息(控制台Network-包名-Headers-Request Headers-Cookie可查看详细信息),从而减少 Cookie 被盗取的可能性;
  • 但由于网站本身可能也需要获取 Cookie 的信息,因此通常来说,我们只会在部分重要的 Cookie 上(如密码)设置 httpOnly 属性;
  • 无法从根本上解决XSS,只是一种减少XSS伤害的措施。


    给cookie设置httpOnly

2. 输入检查

(1)白名单
  • 定义:判断输入格式,只允许通过特定格式的字符。
  • 对于只允许用户提交纯文本的情况下。例如注册帐号时,使用白名单的形式检测邮箱的格式是否正确;
  • 对于允许用户提交一些自定义 HTML 代码的情况下(富文本),如评论框、帖子的内容有图片、链接、表格等(需要通过 HTML 代码来实现)。使用白名单的形式(只可以使用指定的标签和属性)来实现输入检查。
(2)黑名单
  • 定义:收到数据时过滤危险字符(各种标签与属性,如:<script>,<style>,<iframe>,onclick,onerror等),或者转义特殊字符(如:<-->&lt;,>-->&gt;,&-->&amp;,\-->&quot;,"-->&quot;,'-->&#39;等)
  • 对于允许用户提交一些自定义 HTML 代码的情况下(富文本),可以使用黑名单来过滤与转义危险字符。
  • 过滤与转义需前端与服务端配合使用,因为可以使用某些工具(如Node)绕过前端检测,直接发送数据给服务端。
  • 参考代码如下:
// 正则获取危险标签
var REGEXP_TAG = /<(script|style|iframe)[^<>]*?>.*?<\/\1>/ig;
// 正则获取危险标签属性
var REGEXP_ATTR_NAME = /(onerror|onclick)=([\"\']?)([^\"\'>]*?)\2/ig;

/**
 * 过滤函数
 * @param {String} str
 */
function filter(str) {
  return String(str)
    .replace(REGEXP_TAG, '')
    .replace(REGEXP_ATTR_NAME, '');
}

/**
 * 转义 HTML 特殊字符
 * @param {String} str
 */
function htmlEncode(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}
  • 拓展

事实上本文所实现的输入检查逻辑并不完善,在真实的业务开发中,输入检查所做的工作更为全面和复杂。目前有许多十分完善通用的 XSS 防范的代码库,大家可以结合理解去阅读和试用下:

3. 输出检查

用户数据经过服务器处理被填充到 HTML 代码中,可能存在以下五个场景:

  • HTML 标签中(用户输入将在 HTML 解析环境进行)
  • HTML 属性中(用户输入将在 HTML 解析环境进行)
  • script 标签中 (用户输入将在 JavaScript 解析环境进行)
  • HTML 事件属性中(用户输入将在 JavaScript 解析环境进行)
  • 地址栏中(用户输入将在 URL 解析环境进行)

如下图所示:($var表示用户数据)

输出场景

因此,为了避免我们用户输入被当做代码来执行,我们需要对用户输入中存在的特殊字符做一些处理。处理规则如下所示:

  • HTML 解析环境使用 HtmlEncode
function htmlEncode(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}
  • JavaScript 解析环境使用 JavaScriptEncode
  // 通常是使用"\"对特殊字符进行转义
  // 实际情况比较复杂,此处为简单例子
  function JavaScriptEncode(str) {
    function encodeCharx(original) {
      var thecharchar = original.charAt(0);
      switch(thecharchar) {
        case '\n': return "\\n"; break;
        case '\r': return "\\r"; break;
        case '\'': return "\\'"; break;
        case '"': return "\\x22"; break;
        case '\&': return "\\&"; break;
        case '\\': return "\\\\"; break;
        case '\t': return "\\t"; break;
        case '/': return "\\x2F"; break;
        case '<': return "\\x3C"; break;
        case '>': return "\\x3E"; break;
        default: return thecharchar;
      }
    }
    var preescape = str;
    var escaped = "";
    for(var i=0; i < preescape.length; i++){
      escaped = escaped + encodeCharx(preescape.charAt(i));
    }
    return escaped;
  }
  • URL 解析环境使用 URLEncode
  // 直接使用encodeURI()编码就行
  var url = encodeURI($test);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,874评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,151评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,270评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,137评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,116评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,935评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,261评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,895评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,342评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,854评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,978评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,609评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,181评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,182评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,402评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,376评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,677评论 2 344

推荐阅读更多精彩内容

  • 跨站脚本(XSS)是web应用中的一种典型的计算机安全漏洞。XSS允许攻击者可以在其他用户浏览的web页面中注入客...
    留七七阅读 7,893评论 1 26
  • 攻击活动 SQL(结构化查询语言)注入 概述 一个SQL注入攻击包含了从应用客户端的输入数据中注入或嵌入的方式,一...
    夏夜星语阅读 898评论 0 0
  • 1、漏洞概述 XSS 是指攻击者在网页中嵌入客户端脚本,通常是 JavaScript 编写的恶意代码,当用户使 用...
    linkally阅读 1,686评论 2 10
  • 之前积累了XSS 有一段时间,因为目前开始了一件有趣的工程,需要整合非常多的知识,其中Web 安全这一块出现最多的...
    刀背藏身阅读 9,033评论 0 16
  • 生活还是留下点记忆的好,留下些文字,愈加弥久,相较与记忆,更加可靠! 初三,去了舅舅家 每年去舅舅家,成了人...
    茶与书阅读 469评论 2 0