根據白名單過濾 HTML(防止 XSS 攻擊)


https://github.com/leizongmin/js-xss/blob/master/README.zh.md

根據白名單過濾 HTML(防止 XSS 攻擊)

xss


xss是一個用於對用戶輸入的內容進行過濾,以避免遭受 XSS 攻擊的模塊(什么是 XSS 攻擊?)。主要用於論壇、博客、網上商店等等一些可允許用戶錄入頁面排版、格式控制相關的 HTML 的場景,xss模塊通過白名單來控制允許的標簽及相關的標簽屬性,另外還提供了一系列的接口以便用戶擴展,比其他同類模塊更為靈活。

項目主頁: http://jsxss.com

在線測試: http://jsxss.com/zh/try.html


特性

  • 白名單控制允許的 HTML 標簽及各標簽的屬性
  • 通過自定義處理函數,可對任意標簽及其屬性進行處理

參考資料

性能(僅作參考)

  • xss 模塊:8.2 MB/s
  • validator@0.3.7 模塊的 xss()函數:4.4 MB/s

測試代碼參考 benchmark 目錄

安裝

NPM

$ npm install xss

Bower

$ bower install xss

或者

$ bower install https://github.com/leizongmin/js-xss.git

使用方法

在 Node.js 中使用

var xss = require("xss"); var html = xss('<script>alert("xss");</script>'); console.log(html);

在瀏覽器端使用

Shim 模式(參考文件 test/test.html):

<script src="https://raw.github.com/leizongmin/js-xss/master/dist/xss.js"></script> <script> // 使用函數名 filterXSS,用法一樣 var html = filterXSS('<script>alert("xss");</scr' + 'ipt>'); alert(html); </script>

AMD 模式(參考文件 test/test_amd.html):

<script> require.config({  baseUrl: './',  paths: {  xss: 'https://raw.github.com/leizongmin/js-xss/master/dist/xss.js'  },  shim: {  xss: {exports: 'filterXSS'}  } }) require(['xss'], function (xss) {  var html = xss('<script>alert("xss");</scr' + 'ipt>');  alert(html); }); </script>

使用命令行工具來對文件進行 XSS 處理

處理文件

可通過內置的 xss 命令來對輸入的文件進行 XSS 處理。使用方法:

xss -i <源文件> -o <目標文件>

例:

$ xss -i origin.html -o target.html

在線測試

執行以下命令,可在命令行中輸入 HTML 代碼,並看到過濾后的代碼:

$ xss -t

詳細命令行參數說明,請輸入 $ xss -h 來查看。

自定義過濾規則

在調用 xss() 函數進行過濾時,可通過第二個參數來設置自定義規則:

options = {}; // 自定義規則 html = xss('<script>alert("xss");</script>', options);

如果不想每次都傳入一個 options 參數,可以創建一個 FilterXSS 實例(使用這種方法速度更快):

options = {};  // 自定義規則
myxss = new xss.FilterXSS(options);
// 以后直接調用 myxss.process() 來處理即可
html = myxss.process('<script>alert("xss");</script>');

options 參數的詳細說明見下文。

白名單

通過 whiteList 來指定,格式為:{'標簽名': ['屬性1', '屬性2']}。不在白名單上的標簽將被過濾,不在白名單上的屬性也會被過濾。以下是示例:

// 只允許a標簽,該標簽只允許href, title, target這三個屬性 var options = { whiteList: { a: ["href", "title", "target"] } }; // 使用以上配置后,下面的HTML // <a href="#" onclick="hello()"><i>大家好</i></a> // 將被過濾為 // <a href="#">大家好</a>

默認白名單參考 xss.whiteList

自定義匹配到標簽時的處理方法

通過 onTag 來指定相應的處理函數。以下是詳細說明:

function onTag(tag, html, options) { // tag是當前的標簽名稱,比如<a>標簽,則tag的值是'a' // html是該標簽的HTML,比如<a>標簽,則html的值是'<a>' // options是一些附加的信息,具體如下: // isWhite boolean類型,表示該標簽是否在白名單上 // isClosing boolean類型,表示該標簽是否為閉合標簽,比如</a>時為true // position integer類型,表示當前標簽在輸出的結果中的起始位置 // sourcePosition integer類型,表示當前標簽在原HTML中的起始位置 // 如果返回一個字符串,則當前標簽將被替換為該字符串 // 如果不返回任何值,則使用默認的處理方法: // 在白名單上: 通過onTagAttr來過濾屬性,詳見下文 // 不在白名單上:通過onIgnoreTag指定,詳見下文 }

自定義匹配到標簽的屬性時的處理方法

通過 onTagAttr 來指定相應的處理函數。以下是詳細說明:

function onTagAttr(tag, name, value, isWhiteAttr) { // tag是當前的標簽名稱,比如<a>標簽,則tag的值是'a' // name是當前屬性的名稱,比如href="#",則name的值是'href' // value是當前屬性的值,比如href="#",則value的值是'#' // isWhiteAttr是否為白名單上的屬性 // 如果返回一個字符串,則當前屬性值將被替換為該字符串 // 如果不返回任何值,則使用默認的處理方法 // 在白名單上: 調用safeAttrValue來過濾屬性值,並輸出該屬性,詳見下文 // 不在白名單上:通過onIgnoreTagAttr指定,詳見下文 }

自定義匹配到不在白名單上的標簽時的處理方法

通過 onIgnoreTag 來指定相應的處理函數。以下是詳細說明:

function onIgnoreTag(tag, html, options) { // 參數說明與onTag相同 // 如果返回一個字符串,則當前標簽將被替換為該字符串 // 如果不返回任何值,則使用默認的處理方法(通過escape指定,詳見下文) }

自定義匹配到不在白名單上的屬性時的處理方法

通過 onIgnoreTagAttr 來指定相應的處理函數。以下是詳細說明:

function onIgnoreTagAttr(tag, name, value, isWhiteAttr) { // 參數說明與onTagAttr相同 // 如果返回一個字符串,則當前屬性值將被替換為該字符串 // 如果不返回任何值,則使用默認的處理方法(刪除該屬) }

自定義 HTML 轉義函數

通過 escapeHtml 來指定相應的處理函數。以下是默認代碼 (不建議修改) :

function escapeHtml(html) { return html.replace(/</g, "&lt;").replace(/>/g, "&gt;"); }

自定義標簽屬性值的轉義函數

通過 safeAttrValue 來指定相應的處理函數。以下是詳細說明:

function safeAttrValue(tag, name, value) { // 參數說明與onTagAttr相同(沒有options參數) // 返回一個字符串表示該屬性值 }

自定義 CSS 過濾器

如果配置中允許了標簽的 style 屬性,則它的值會通過cssfilter 模塊處理。 cssfilter 模塊包含了一個默認的 CSS 白名單,你可以通過以下的方式配置:

myxss = new xss.FilterXSS({ css: { whiteList: { position: /^fixed|relative$/, top: true, left: true } } }); html = myxss.process('<script>alert("xss");</script>');

如果不想使用 CSS 過濾器來處理 style 屬性的內容,可指定 css 選項的值為 false

myxss = new xss.FilterXSS({ css: false });

要獲取更多的幫助信息可看這里:https://github.com/leizongmin/js-css-filter

快捷配置

去掉不在白名單上的標簽

通過 stripIgnoreTag 來設置:

  • true:去掉不在白名單上的標簽
  • false:(默認),使用配置的escape函數對該標簽進行轉義

示例:

當設置 stripIgnoreTag = true時,以下代碼

code:<script>alert(/xss/);</script>

過濾后將輸出

code:alert(/xss/);

去掉不在白名單上的標簽及標簽體

通過 stripIgnoreTagBody 來設置:

  • false|null|undefined:(默認),不特殊處理
  • '*'|true:去掉所有不在白名單上的標簽
  • ['tag1', 'tag2']:僅去掉指定的不在白名單上的標簽

示例:

當設置 stripIgnoreTagBody = ['script']時,以下代碼

code:<script>alert(/xss/);</script>

過濾后將輸出

code:

去掉 HTML 備注

通過 allowCommentTag 來設置:

  • true:不處理
  • false:(默認),自動去掉 HTML 中的備注

示例:

當設置 allowCommentTag = false 時,以下代碼

code:<!-- something --> END

過濾后將輸出

code: END

應用實例

允許標簽以 data-開頭的屬性

var source = '<div a="1" b="2" data-a="3" data-b="4">hello</div>'; var html = xss(source, { onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) { if (name.substr(0, 5) === "data-") { // 通過內置的escapeAttrValue函數來對屬性值進行轉義 return name + '="' + xss.escapeAttrValue(value) + '"'; } } }); console.log("%s\nconvert to:\n%s", source, html);

運行結果:

<div a="1" b="2" data-a="3" data-b="4">hello</div> convert to: <div data-a="3" data-b="4">hello</div>

允許名稱以 x-開頭的標簽

var source = "<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>"; var html = xss(source, { onIgnoreTag: function(tag, html, options) { if (tag.substr(0, 2) === "x-") { // 不對其屬性列表進行過濾 return html; } } }); console.log("%s\nconvert to:\n%s", source, html);

運行結果:

<x><x-1>he<x-2 checked></x-2>wwww</x-1><a> convert to: &lt;x&gt;<x-1>he<x-2 checked></x-2>wwww</x-1><a>

分析 HTML 代碼中的圖片列表

var source = '<img src="img1">a<img src="img2">b<img src="img3">c<img src="img4">d'; var list = []; var html = xss(source, { onTagAttr: function(tag, name, value, isWhiteAttr) { if (tag === "img" && name === "src") { // 使用內置的friendlyAttrValue函數來對屬性值進行轉義,可將&lt;這類的實體標記轉換成打印字符< list.push(xss.friendlyAttrValue(value)); } // 不返回任何值,表示還是按照默認的方法處理 } }); console.log("image list:\n%s", list.join(", "));

運行結果:

image list:
img1, img2, img3, img4

去除 HTML 標簽(只保留文本內容)

var source = "<strong>hello</strong><script>alert(/xss/);</script>end"; var html = xss(source, { whiteList: [], // 白名單為空,表示過濾所有標簽 stripIgnoreTag: true, // 過濾所有非白名單標簽的HTML stripIgnoreTagBody: ["script"] // script標簽較特殊,需要過濾標簽中間的內容 }); console.log("text: %s", html);

運行結果:

text: helloend

授權協議

Copyright (c) 2012-2017 Zongmin Lei(雷宗民) <leizongmin@gmail.com>
http://ucdok.com

The MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM