2017-03-08 13:41:05 -05:00
|
|
|
/* eslint-env browser, jquery */
|
2016-08-14 06:32:22 -04:00
|
|
|
// allow some attributes
|
2018-11-10 14:24:41 -05:00
|
|
|
|
2021-02-15 03:42:51 -05:00
|
|
|
const filterXSS = require('xss')
|
2018-11-10 14:24:41 -05:00
|
|
|
|
2021-02-15 03:42:51 -05:00
|
|
|
const whiteListAttr = ['id', 'class', 'style']
|
2017-03-08 13:41:05 -05:00
|
|
|
window.whiteListAttr = whiteListAttr
|
2017-03-22 06:26:35 -04:00
|
|
|
// allow link starts with '.', '/' and custom protocol with '://', exclude link starts with javascript://
|
2021-02-15 03:42:51 -05:00
|
|
|
const linkRegex = /^(?!javascript:\/\/)([\w|-]+:\/\/)|^([.|/])+/i
|
2016-08-14 23:00:02 -04:00
|
|
|
// allow data uri, from https://gist.github.com/bgrins/6194623
|
2021-02-15 03:42:51 -05:00
|
|
|
const dataUriRegex = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@/?%\s]*)\s*$/i
|
2016-08-14 06:32:22 -04:00
|
|
|
// custom white list
|
2021-02-15 03:42:51 -05:00
|
|
|
const whiteList = filterXSS.whiteList
|
2016-08-14 06:32:22 -04:00
|
|
|
// allow ol specify start number
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.ol = ['start']
|
2017-02-17 08:56:35 -05:00
|
|
|
// allow li specify value number
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.li = ['value']
|
2016-08-14 06:32:22 -04:00
|
|
|
// allow style tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.style = []
|
2016-08-14 06:32:22 -04:00
|
|
|
// allow kbd tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.kbd = []
|
2016-08-14 06:32:22 -04:00
|
|
|
// allow ifram tag with some safe attributes
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.iframe = ['allowfullscreen', 'name', 'referrerpolicy', 'src', 'width', 'height']
|
2018-02-26 07:54:57 -05:00
|
|
|
// allow summary tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.summary = []
|
2018-02-25 08:48:50 -05:00
|
|
|
// allow ruby tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.ruby = []
|
2018-02-26 07:55:10 -05:00
|
|
|
// allow rp tag for ruby
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.rp = []
|
2018-02-25 08:48:50 -05:00
|
|
|
// allow rt tag for ruby
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.rt = []
|
2018-02-25 08:48:50 -05:00
|
|
|
// allow figure tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.figure = []
|
2018-02-25 08:48:50 -05:00
|
|
|
// allow figcaption tag
|
2021-02-15 03:42:51 -05:00
|
|
|
whiteList.figcaption = []
|
2016-02-11 15:33:21 -05:00
|
|
|
|
2021-02-15 03:42:51 -05:00
|
|
|
const filterXSSOptions = {
|
2017-03-08 13:41:05 -05:00
|
|
|
allowCommentTag: true,
|
|
|
|
whiteList: whiteList,
|
|
|
|
escapeHtml: function (html) {
|
2017-03-22 06:26:30 -04:00
|
|
|
// allow html comment in multiple lines
|
2017-09-27 06:20:04 -04:00
|
|
|
return html.replace(/<(?!!--)/g, '<').replace(/-->/g, '__HTML_COMMENT_END__').replace(/>/g, '>').replace(/__HTML_COMMENT_END__/g, '-->')
|
2017-03-08 13:41:05 -05:00
|
|
|
},
|
|
|
|
onIgnoreTag: function (tag, html, options) {
|
2017-03-22 06:26:30 -04:00
|
|
|
// allow comment tag
|
2017-03-08 13:41:05 -05:00
|
|
|
if (tag === '!--') {
|
2019-05-30 18:27:56 -04:00
|
|
|
// do not filter its attributes
|
2018-12-28 03:42:55 -05:00
|
|
|
return html.replace(/<(?!!--)/g, '<').replace(/-->/g, '__HTML_COMMENT_END__').replace(/>/g, '>').replace(/__HTML_COMMENT_END__/g, '-->')
|
2017-03-08 13:41:05 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
onTagAttr: function (tag, name, value, isWhiteAttr) {
|
2017-03-22 06:26:30 -04:00
|
|
|
// allow href and src that match linkRegex
|
2017-03-08 13:41:05 -05:00
|
|
|
if (isWhiteAttr && (name === 'href' || name === 'src') && linkRegex.test(value)) {
|
|
|
|
return name + '="' + filterXSS.escapeAttrValue(value) + '"'
|
|
|
|
}
|
2017-03-22 06:26:30 -04:00
|
|
|
// allow data uri in img src
|
2017-03-08 13:41:05 -05:00
|
|
|
if (isWhiteAttr && (tag === 'img' && name === 'src') && dataUriRegex.test(value)) {
|
|
|
|
return name + '="' + filterXSS.escapeAttrValue(value) + '"'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onIgnoreTagAttr: function (tag, name, value, isWhiteAttr) {
|
2017-03-22 06:26:30 -04:00
|
|
|
// allow attr start with 'data-' or in the whiteListAttr
|
2017-03-08 13:41:05 -05:00
|
|
|
if (name.substr(0, 5) === 'data-' || window.whiteListAttr.indexOf(name) !== -1) {
|
2017-03-22 06:26:30 -04:00
|
|
|
// escape its value using built-in escapeAttrValue function
|
2017-03-08 13:41:05 -05:00
|
|
|
return name + '="' + filterXSS.escapeAttrValue(value) + '"'
|
2016-02-11 15:33:21 -05:00
|
|
|
}
|
2017-03-08 13:41:05 -05:00
|
|
|
}
|
|
|
|
}
|
2016-02-11 15:33:21 -05:00
|
|
|
|
2017-03-08 13:41:05 -05:00
|
|
|
function preventXSS (html) {
|
|
|
|
return filterXSS(html, filterXSSOptions)
|
2016-10-08 08:02:30 -04:00
|
|
|
}
|
2017-03-08 13:41:05 -05:00
|
|
|
window.preventXSS = preventXSS
|
2016-10-08 08:02:30 -04:00
|
|
|
|
|
|
|
module.exports = {
|
2018-11-10 14:24:41 -05:00
|
|
|
preventXSS: preventXSS,
|
|
|
|
escapeAttrValue: filterXSS.escapeAttrValue
|
2016-10-08 08:02:30 -04:00
|
|
|
}
|