Skip to content

Commit 5dffae7

Browse files
authored
Merge pull request #1115 from nelstrom/attribute-name-check-with-tagname
feat: add tagName parameter to attributeNameCheck
2 parents f1c9a64 + ec31ba5 commit 5dffae7

File tree

14 files changed

+60
-12
lines changed

14 files changed

+60
-12
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ const clean = DOMPurify.sanitize(dirty, {ALLOW_DATA_ATTR: false});
230230
// The same goes for their attributes. By default, the built-in or configured allow.list is used.
231231
//
232232
// You can use a RegExp literal to specify what is allowed or a predicate, examples for both can be seen below.
233+
// When using a predicate function for attributeNameCheck, it can optionally receive the tagName as a second parameter
234+
// for more granular control over which attributes are allowed for specific elements.
233235
// The default values are very restrictive to prevent accidental XSS bypasses. Handle with great care!
234236

235237
const clean = DOMPurify.sanitize(
@@ -264,6 +266,26 @@ const clean = DOMPurify.sanitize(
264266
},
265267
}
266268
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>
269+
270+
// Example with attributeNameCheck receiving tagName as a second parameter
271+
const clean = DOMPurify.sanitize(
272+
'<element-one attribute-one="1" attribute-two="2"></element-one><element-two attribute-one="1" attribute-two="2"></element-two>',
273+
{
274+
CUSTOM_ELEMENT_HANDLING: {
275+
tagNameCheck: (tagName) => tagName.match(/^element-(one|two)$/),
276+
attributeNameCheck: (attr, tagName) => {
277+
if (tagName === 'element-one') {
278+
return ['attribute-one'].includes(attr);
279+
} else if (tagName === 'element-two') {
280+
return ['attribute-two'].includes(attr);
281+
} else {
282+
return false;
283+
}
284+
},
285+
allowCustomizedBuiltInElements: false,
286+
},
287+
}
288+
); // <element-one attribute-one="1"></element-one><element-two attribute-two="2"></element-two>
267289
```
268290
### Control behavior relating to URI values
269291
```js

dist/purify.cjs.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ interface Config {
7676
* Regular expression or function to match to allowed attributes.
7777
* Default is null (disallow any attributes not on the allow list).
7878
*/
79-
attributeNameCheck?: RegExp | ((attributeName: string) => boolean) | null | undefined;
79+
attributeNameCheck?: RegExp | ((attributeName: string, tagName?: string) => boolean) | null | undefined;
8080
/**
8181
* Allow custom elements derived from built-ins if they pass `tagNameCheck`. Default is false.
8282
*/

dist/purify.cjs.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.cjs.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.es.d.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ interface Config {
7676
* Regular expression or function to match to allowed attributes.
7777
* Default is null (disallow any attributes not on the allow list).
7878
*/
79-
attributeNameCheck?: RegExp | ((attributeName: string) => boolean) | null | undefined;
79+
attributeNameCheck?: RegExp | ((attributeName: string, tagName?: string) => boolean) | null | undefined;
8080
/**
8181
* Allow custom elements derived from built-ins if they pass `tagNameCheck`. Default is false.
8282
*/

dist/purify.es.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ function createDOMPurify() {
996996
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
997997
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
998998
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
999-
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
999+
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||
10001000
// Alternative, second condition checks if it's an `is`-attribute, AND
10011001
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
10021002
lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {

dist/purify.es.mjs.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)