feat: single-quoted attribute value syntax support (#287)

This commit is contained in:
mdk000
2024-03-03 03:21:40 +01:00
committed by GitHub
parent 8884b21308
commit bedb0c09db
5 changed files with 37 additions and 1 deletions

View File

@@ -280,6 +280,20 @@ function safeAttrValue(tag, name, value) {
}
```
### Customize output attribute value syntax for HTML
By specifying a `singleQuotedAttributeValue`. Use `true` for `'`. Otherwise default `"` will be used
```javascript
var options = {
singleQuotedAttributeValue: true,
};
// With the configuration specified above, the following HTML:
// <a href="#">Hello</a>
// would become:
// <a href='#'>Hello</a>
```
### Customize CSS filter
If you allow the attribute `style`, the value will be processed by [cssfilter](https://github.com/leizongmin/js-css-filter) module. The cssfilter module includes a default css whitelist. You can specify the options for cssfilter module like this:

View File

@@ -455,5 +455,6 @@ exports.onIgnoreTagStripAll = onIgnoreTagStripAll;
exports.StripTagBody = StripTagBody;
exports.stripCommentTag = stripCommentTag;
exports.stripBlankChar = stripBlankChar;
exports.attributeWrapSign = '"';
exports.cssFilter = defaultCSSFilter;
exports.getDefaultCSSWhiteList = getDefaultCSSWhiteList;

View File

@@ -100,6 +100,8 @@ function FilterXSS(options) {
options.whiteList = DEFAULT.whiteList;
}
this.attributeWrapSign = options.singleQuotedAttributeValue === true ? "'" : DEFAULT.attributeWrapSign;
options.onTag = options.onTag || DEFAULT.onTag;
options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr;
options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag;
@@ -137,6 +139,7 @@ FilterXSS.prototype.process = function (html) {
var onIgnoreTagAttr = options.onIgnoreTagAttr;
var safeAttrValue = options.safeAttrValue;
var escapeHtml = options.escapeHtml;
var attributeWrapSign = me.attributeWrapSign;
var cssFilter = me.cssFilter;
// remove invisible characters
@@ -190,7 +193,7 @@ FilterXSS.prototype.process = function (html) {
// call `safeAttrValue()`
value = safeAttrValue(tag, name, value, cssFilter);
if (value) {
return name + '="' + value + '"';
return name + '=' + attributeWrapSign + value + attributeWrapSign;
} else {
return name;
}

View File

@@ -428,6 +428,22 @@ describe("test XSS", function() {
);
});
it("#singleQuotedAttributeValue", function() {
assert.equal(xss('<a title="xx">not-defined</a>'), '<a title="xx">not-defined</a>');
assert.equal(
xss('<a title="xx">single-quoted</a>', { singleQuotedAttributeValue: true }),
'<a title=\'xx\'>single-quoted</a>'
);
assert.equal(
xss('<a title="xx">double-quoted</a>', { singleQuotedAttributeValue: false }),
'<a title="xx">double-quoted</a>'
);
assert.equal(
xss('<a title="xx">invalid-value</a>', { singleQuotedAttributeValue: 'invalid' }),
'<a title="xx">invalid-value</a>'
);
})
it("no options mutated", function() {
var options = {};

2
typings/xss.d.ts vendored
View File

@@ -22,6 +22,7 @@ declare module "xss" {
stripIgnoreTagBody?: boolean | string[];
allowCommentTag?: boolean;
stripBlankChar?: boolean;
singleQuotedAttributeValue?: boolean;
css?: {} | boolean;
}
@@ -195,6 +196,7 @@ declare module "xss" {
export function onIgnoreTagStripAll(): string;
export const stripCommentTag: EscapeHandler;
export const stripBlankChar: EscapeHandler;
export const attributeWrapSign: string;
export const cssFilter: ICSSFilter;
export function getDefaultCSSWhiteList(): ICSSFilter;