Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate custom elements in configuration #33

Open
0xedward opened this issue Aug 14, 2021 · 3 comments
Open

Validate custom elements in configuration #33

0xedward opened this issue Aug 14, 2021 · 3 comments

Comments

@0xedward
Copy link
Collaborator

0xedward commented Aug 14, 2021

When the user specifies set allowCustomElements to true in sanitizer configuration, we want to allow list all custom elements.

When allowCustomElements === false, we want to remove all custom elements from allowElements.

When allowCustomElements === true, we want to check all elements in allowElements are part of https://wicg.github.io/sanitizer-api/#baseline-elements and keep all custom elements in allowElements. We can construct a regex from https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name to determine if an element is a custom element

For example:

config = { "allowElements" : ["a", "script"], "allowCustomElements" : true}

_normalizeConfig(config) // should throw an error because script is not a custom element and is not in DEFAULT_ALLOWED_ELEMENTS

safeConfig = { "allowElements" : ["a", "mycustomelement"], "allowCustomElements" : true}

_normalizeConfig(config) // should return a config with ["a", "mycustomelement"] for allowElements
@0xedward 0xedward changed the title Add support for custom elements in _transformConfig Add support for custom elements Aug 14, 2021
@0xedward 0xedward changed the title Add support for custom elements Validate custom elements in configuration Aug 14, 2021
@thernstig
Copy link

@0xedward does this mean that this polyfill does not work at all now if using Custom Elements? So this issue needs to be implemented before it can be used in projects using Custom Elements?

@0xedward
Copy link
Collaborator Author

0xedward commented Feb 1, 2023

Hey @thernstig, it's been a while since I worked on this, so my memory might be a bit faulty. The polyfill basically converts the configuration dictionary in the HTML Sanitizer API spec to the equivalent configuration for DOMPurify, then uses DOMPurify to sanitize the input. The polyfill should work if your input has custom elements as long as DOMPurify can handle custom elements without them being specified in its config.

Here's some code pointers for what I mentioned:

let domPurifyConfig = _transformConfig(config);
domPurifyConfig.IN_PLACE = true;
DOMPurify.sanitize(input, domPurifyConfig);

const _transformConfig = function transformConfig(config) {
const allowElems = config.allowElements || [];
const allowAttrs = config.allowAttributes || [];
const blockElements = config.blockElements || [];
const dropElements = config.dropElements || [];
const dropAttrs = config.dropAttributes || [];
// https://github.com/cure53/DOMPurify/issues/556
// To drop elements and their children upon sanitization, those elements need to be in both DOMPurify's FORBID_TAGS and FORBID_CONTENTS lists
const isdropElementsSet =
dropElements !== DEFAULT_DROP_ELEMENTS && dropElements !== [];
const isblockElementsSet =
blockElements !== DEFAULT_BLOCKED_ELEMENTS && blockElements !== [];
let domPurifyConfig = {
ALLOWED_TAGS: allowElems,
ALLOWED_ATTR: allowAttrs,
FORBID_ATTR: dropAttrs,
ALLOW_UNKNOWN_PROTOCOLS: true,
};
if (isdropElementsSet && !isblockElementsSet) {
// Set FORBID_CONTENTS to drop all elements in dropElements
domPurifyConfig.FORBID_TAGS = dropElements;
domPurifyConfig.FORBID_CONTENTS = dropElements;
} else if (isdropElementsSet && isblockElementsSet) {
// Include all dropElements in FORBID_TAGS and specify to only drop elements in dropElements and not elements in blockElements with FORBID_CONTENTS
const union = new Set(blockElements.concat(dropElements));
domPurifyConfig.FORBID_TAGS = Array.from(union);
domPurifyConfig.FORBID_CONTENTS = dropElements;
} else {
domPurifyConfig.FORBID_TAGS = blockElements;
}
return domPurifyConfig;
};

@mozfreddyb
Copy link
Collaborator

So this issue needs to be implemented before it can be used in projects using Custom Elements?

FWIW, I would not recommend using this polyfill in any kind of production setup. The Sanitizer API is still under heavy development and we're changing quite a few things (e.g., the config syntax in WICG/sanitizer-api#181)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants