diff --git a/index.bs b/index.bs index b2503b0..9c51e69 100644 --- a/index.bs +++ b/index.bs @@ -1032,54 +1032,83 @@ beginning with |node|. It consistes of these steps: 1. If |child| is a [=shadow host=], then call [=sanitize core=] on |child|'s [=Element/shadow root=] with |configuration| and |handleJavascriptNavigationUrls|. - 1. Let |elementWithLocalAttributes| be « [] ». - 1. If |configuration|["{{SanitizerConfig/elements}}"] [=map/exists=] and - |configuration|["{{SanitizerConfig/elements}}"] [=SanitizerConfig/contains=] - |elementName|: - 1. Set |elementWithLocalAttributes| to - |configuration|["{{SanitizerConfig/elements}}"][|elementName|]. + 1. If |child|'s [=is value=] is not `null`: + 1. Let |isAttrName| be «[ "`name`" → "`is`", "`namespace`" → null ]». + 1. If [=is attribute allowed=] for |isAttrName| given |configuration|, + and |elementName| is [=/blocked=]: + 1. Set |child|'s [=custom element state=] to "undefined". + 1. Set |child|'s [=custom element definition=] to `null`. + 1. Set |child|'s [=is value=] to `null`. 1. [=list/iterate|For each=] |attribute| in |child|'s [=Element/attribute list=]: 1. Let |attrName| be a {{SanitizerAttributeNamespace}} with |attribute|'s [=Attr/local name=] and [=Attr/namespace=]. - - 1. If |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/removeAttributes}}"] [=map/with default=] « » - [=SanitizerConfig/contains=] |attrName|: - 1. [=/remove an attribute|Remove=] |attribute|. - 1. Otherwise, if |configuration|["{{SanitizerConfig/attributes}}"] [=map/exists=]: - 1. If |configuration|["{{SanitizerConfig/attributes}}"] does not - [=SanitizerConfig/contain=] |attrName| and - |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] [=map/with default=] « » - does not [=SanitizerConfig/contain=] |attrName|, and if - "data-" is not a [=code unit prefix=] of |attribute|'s [=Attr/local name=] and - [=Attr/namespace=] is not `null` or - |configuration|["{{SanitizerConfig/dataAttributes}}"] is not true: - 1. [=/remove an attribute|Remove=] |attribute|. - 1. Otherwise: - 1. If |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] - [=map/exists=] and |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] does not [=SanitizerConfig/contain=] |attrName|: - 1. [=/remove an attribute|Remove=] |attribute|. - - 1. Otherwise, if |configuration|["{{SanitizerConfig/removeAttributes}}"] [=SanitizerConfig/contains=] |attrName|: - 1. [=/remove an attribute|Remove=] |attribute|. - + 1. If [=is attribute allowed=] for |attrName| given |configuration|, + and |elementName| is [=/blocked=], + then [=/remove an attribute|remove=] |attribute|. 1. If |handleJavascriptNavigationUrls|: - 1. If «[|elementName|, |attrName|]» matches an entry in - the [=built-in navigating URL attributes list=], and if |attribute| - [=contains a javascript: URL=], then [=/remove an attribute|remove=] |attribute|. - 1. If |child|'s [=Element/namespace=] [=string/is=] the - [=MathML Namespace=] and |attr|'s [=Attr/local name=] [=string/is=] - "`href`" and |attr|'s [=Attr/namespace=] is `null` or the - [=XLink namespace=] and |attr| [=contains a javascript: URL=], - then [=/remove an attribute|remove=] |attribute|. - 1. If the [=built-in animating URL attributes list=] - [=SanitizerConfig/contains=] - «[|elementName|, |attrName|]» and |attr|'s - [=get an attribute value|value=] [=string/is=] "`href`" or - "`xlink:href`", then [=/remove an attribute|remove=] |attribute|. + 1. If «[|elementName|, |attrName|]» matches an entry in + the [=built-in navigating URL attributes list=], and if |attribute| + [=contains a javascript: URL=], then [=/remove an attribute|remove=] + |attribute|. + 1. If |child|'s [=Element/namespace=] [=string/is=] the + [=MathML Namespace=] and |attr|'s [=Attr/local name=] [=string/is=] + "`href`" and |attr|'s [=Attr/namespace=] is `null` or the + [=XLink namespace=] and |attr| [=contains a javascript: URL=], + then [=/remove an attribute|remove=] |attribute|. + 1. If the [=built-in animating URL attributes list=] + [=SanitizerConfig/contains=] + «[|elementName|, |attrName|]» and |attr|'s + [=get an attribute value|value=] [=string/is=] "`href`" or + "`xlink:href`", then [=/remove an attribute|remove=] |attribute|. 1. Call [=sanitize core=] on |child| with |configuration| and |handleJavascriptNavigationUrls|. +
+To determine is attribute allowed for a +{{SanitizerAttributeNamespace}} |attrName|, +given a {{SanitizerConfig}} |configuration|, +and an {{SanitizerElementNamespace}} |elementName|: + +1. Let |elementWithLocalAttributes| be an empty [=ordered map=]. +1. If |configuration|["{{SanitizerConfig/elements}}"] [=map/exists=] and + |configuration|["{{SanitizerConfig/elements}}"] [=SanitizerConfig/contains=] + |elementName|: + 1. Set |elementWithLocalAttributes| to the |item| in + |configuration|["{{SanitizerConfig/elements}}"] where + |elementName|["{{SanitizerElementNamespace/name}}"] [=string/is=] + |item|["{{SanitizerElementNamespace/name}}"] and + |elementName|["{{SanitizerElementNamespace/namespace}}"] [=string/is=] + |item|["{{SanitizerElementNamespace/namespace}}"]. +1. If |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/removeAttributes}}"] [=map/with default=] « » + [=SanitizerConfig/contains=] |attrName|: + 1. Return [=/blocked=]. +1. If |configuration|["{{SanitizerConfig/attributes}}"] [=map/exists=]: + 1. Let the [=boolean=] |globallyAllowed| be whether + |configuration|["{{SanitizerConfig/attributes}}"] + [=SanitizerConfig/contains=] |attrName|. + 1. Let the [=boolean=] |locallyAllowed| be whether + |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] [=map/with default=] « » + [=SanitizerConfig/contains=] |attrName|. + 1. Let the [=boolean=] |isDataAttributeAllowed| be whether both, + "data-" is a [=code unit prefix=] of + |attrName|[{{SanitizerAttributeNamespace/name}}] and + |attrName|[{{SanitizerAttributeNamespace/namespace}}] is `null`, and + |configuration|["{{SanitizerConfig/dataAttributes}}"] is true. + 1. If neither |globallyAllowed| nor |locallyAllowed| nor + |isDataAttributeAllowed|, return [=/blocked=]. +1. Otherwise: + 1. If |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] + [=map/exists=] and |elementWithLocalAttributes|["{{SanitizerElementNamespaceWithAttributes/attributes}}"] does not [=SanitizerConfig/contain=] |attrName|: + 1. Return [=/blocked=]. + 1. Otherwise, if |configuration|["{{SanitizerConfig/removeAttributes}}"] + [=SanitizerConfig/contains=] |attrName|: + 1. Return [=/blocked=]. +1. Return [=/allowed=]. + +
+ +
Note: Current browsers support `javascript:` URLs only when navigating. Since navigation itself is not an XSS threat we handle