XSS学习笔记

2018-03-12  本文已影响0人  One_Hund

一、XSS 简介

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

攻击方式如下图所示:


XSS攻击

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

(1)反射型(非持久型)XSS
(2)存储型(持久型)XSS
(3)DOM-Basedx型 XSS

二、XSS payload

三、XSS 防御

1. 给cookie设置httpOnly

2. 输入检查

(1)白名单
(2)黑名单
// 正则获取危险标签
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 代码中,可能存在以下五个场景:

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

输出场景

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

function htmlEncode(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}
  // 通常是使用"\"对特殊字符进行转义
  // 实际情况比较复杂,此处为简单例子
  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;
  }
  // 直接使用encodeURI()编码就行
  var url = encodeURI($test);
上一篇 下一篇

猜你喜欢

热点阅读