可以去這里下載xss.js https://github.com/leizongmin/js-xss
基本的使用說明在git上都有了
說一下我工作中額外使用的
一般后台返回的內容中包含 【標簽】的;
遇到的情況一:返回的內容中包含style標簽,如下
returnstr : ' 您好! 2019年10月工資已核發完成,請登陸HR系統或訪問OTP查詢您的薪資單明細。 請點擊下方鏈接進入:
<br> <a href="https://hrapppw.oa.">查看本月工資</a>
<style>
p{ font-family: 'Microsoft YaHei'; color: #333333; }
a { text-decoration: underline;color:blue; }
</style> ';
默認的白名單上【getDefaultWhiteList函數返回的數組中】沒有style標簽,那么,此時的 style就進入onTag方法中,再進入onIgnoreTag中;
在白名單上: 通過onTagAttr來過濾屬性
不在白名單上:通過onIgnoreTag指定
這樣就會被渲染成字符串,就不會對返回的這段文本的樣式進行渲染,這時我們需要做的就是將style添加到白名單標簽中(getDefaultWhiteList返回的數組中)
function getDefaultWhiteList() { return { a: ["target", "href", "title"], abbr: ["title"], address: [], area: ["shape", "coords", "href", "alt"], article: [], aside: [], audio: ["autoplay", "controls", "loop", "preload", "src"], b: [], bdi: ["dir"], bdo: ["dir"], big: [], blockquote: ["cite"], br: [], caption: [], center: [], cite: [], code: [], col: ["align", "valign", "span", "width"], colgroup: ["align", "valign", "span", "width"], dd: [], del: ["datetime"], details: ["open"], div: [], dl: [], dt: [], em: [], font: ["color", "size", "face"], footer: [], h1: [], h2: [], h3: [], h4: [], h5: [], h6: [], header: [], hr: [], i: [], img: ["src", "alt", "title", "width", "height"], ins: ["datetime"], li: [], mark: [], nav: [], ol: [], p: [], pre: [], s: [], section: [], small: [], span: [], sub: [], sup: [], strong: [], table: ["width", "border", "align", "valign","style"], tbody: ["align", "valign"], td: ["width", "rowspan", "colspan", "align", "valign","style"], tfoot: ["align", "valign"], th: ["width", "rowspan", "colspan", "align", "valign"], thead: ["align", "valign"], tr: ["rowspan", "align", "valign"], tt: [], u: [], ul: [], video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"], style:[] //新添 }; }
遇到的情況二:返回的內容中包含td標簽,標簽上有內聯樣式,如下
returnstr:' <table style="color:red"><td>style="color:green"</td></table> '
出現的問題是:顏色沒有被渲染;
原因是 : 默認的白名單標簽中的td上是沒有內連樣式style的,
解決:td: ["width", "rowspan", "colspan", "align", "valign","style"],
video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"],
style:[]
類似的問題,當渲染出現不符合心中預期的時候,就去看是否要渲染的標簽或者屬性不在白名單上,或者是在白名單上
也可以根據文檔,自定義渲染函數
下文是git上的中文文檔
性能(僅作參考)
xss 模塊:8.2 MB/s
validator@0.3.7 模塊的 xss()函數:4.4 MB/s
測試代碼參考 benchmark 目錄
github地址 https://github.com/leizongmin/js-xss/blob/master/README.zh.md
安裝
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, "<").replace(/>/g, ">");
}
自定義標簽屬性值的轉義函數
通過 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:
<x><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函數來對屬性值進行轉義,可將<這類的實體標記轉換成打印字符<
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
以上的git地址以及中文文檔,來自原博主,有需要可以過去看,這里僅作為jit連不上的時候,記錄方便查看