From 4690012be28ff2df3cb0f84bf740bbfd2581aa6a Mon Sep 17 00:00:00 2001 From: Daniel Vogelheim Date: Thu, 28 Nov 2024 13:39:36 +0100 Subject: [PATCH 1/6] wip --- index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 0f58238..42f2291 100644 --- a/index.bs +++ b/index.bs @@ -222,8 +222,9 @@ The family of {{Element/setHTML()}}-like methods all accept an options dictionary. Right now, only one member of this dictionary is defined:
+enum SanitizerPresets { "default" };
 dictionary SetHTMLOptions {
-  (Sanitizer or SanitizerConfig) sanitizer = {};
+  (Sanitizer or SanitizerConfig or SanitizerPresets) sanitizer = "default";
 };
 
From ffa2d6af70e4d4cc8009af5e8a2d6d5d1ca183f2 Mon Sep 17 00:00:00 2001 From: Daniel Vogelheim Date: Fri, 29 Nov 2024 13:19:36 +0100 Subject: [PATCH 2/6] draft --- index.bs | 70 +++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/index.bs b/index.bs index 42f2291..de2323a 100644 --- a/index.bs +++ b/index.bs @@ -259,12 +259,12 @@ interface Sanitizer { // Remove markup that executes script. May modify multiple lists: undefined removeUnsafe(); + + // Create a Sanitizer instance using the built-in defaults. + [NewObject] static Sanitizer getDefault(); }; -Note: {{Sanitizer}} will likely get an additional method: -
`[NewObject] static Sanitizer getDefault();` - A {{Sanitizer}} has an associated configuration, a {{SanitizerConfig}}.
@@ -316,6 +316,11 @@ update [=this=]'s [=Sanitizer/configuration=] with the result of calling [=remov on [=this=]'s [=Sanitizer/configuration=].
+
+The getDefault method steps are to return the +result of [=get a sanitizer instance from options=] with «[ "{{SetHTMLOptions/sanitizer}}" → "{{SanitizerPresets/default}}" ]» +
+ ## The Configuration Dictionary ## {#config}
@@ -374,25 +379,27 @@ To set and filter HTML, given an {{Element}} or {{DocumentFragment}}
 
 
 
-To get a sanitizer instance from options for -an options dictionary |options|, do: +To get a sanitizer instance from options from +a [=dictionary=] |options|, do: -1. [=Assert=]: |options| is a [=dictionary=]. -1. If |options|["`sanitizer`"] doesn't [=map/exist=], then: - 1. Let |result| be a new {{Sanitizer}} instance. - 1. Let |setConfigurationResult| be the result of [=set a configuration=] - with an empty [=dictionary=] on |result|. - 1. [=Assert=]: The |setConfigurationResult| is true. - 1. Return |result|. -1. [=Assert=]: |options|["`sanitizer`"] is either a {{Sanitizer}} instance +1. Let |sanitizerSpec| be "{{SanitizerPresets/default}}". +1. If |options|["{{SetHTMLOptions/sanitizer}}"] [=map/exists=], then: + 1. Let |sanitizerSpec| be |options|["{{SetHTMLOptions/sanitizer}}"] +1. [=Assert=]: |sanitizerSpec| is either a {{Sanitizer}} instance, + a [=string=] which is a {{SanitizerPresets}} member, or a [=dictionary=]. +1. If |sanitizerSpec| is a [=string=]: + 1. [=Assert=]: |sanitizerSpec| [=is=] "{{SanitizerPresets/default}}" + 1. Let |sanitizerSpec| be the [=built-in safe default configuration=]. +1. [=Assert=]: |sanitizerSpec| is either a {{Sanitizer}} instance, or a [=dictionary=]. -1. If |options|["`sanitizer`"] is a {{Sanitizer}} instance: - Then return |options|["`sanitizer`"]. -1. [=Assert=]: |options|["`sanitizer`"] is a [=dictionary=]. -1. Let |result| be a new {{Sanitizer}} instance. -1. Call [=set a configuration=] with |options|["`sanitizer`"]. -1. If [=set a configuration=] returned false, [=throw=] a {{TypeError}}. -1. Otherwise, return |result|. +1. If |sanitizerSpec| is a [=dictionary=]: + 1. Let |sanitizer| be a new {{Sanitizer}} instance. + 1. Let |setConfigurationResult| be the result of [=set a configuration=] + with |sanitizerSpec| on |sanitizer|. + 1. If |setConfigurationResult| is false, [=throw=] a {{TypeError}}. + 1. Let |sanitizerSpec| be |sanitizer|. +1. [=Assert=]: |sanitizerSpec| is a {{Sanitizer}} instance. +1. Return |sanitizerSpec|.
@@ -463,7 +470,7 @@ template contents). It consistes of these steps: [=Attr/namespace=] is `null` and |configuration|["{{SanitizerConfig/dataAttributes}}"] is true 1. If |handleJavascriptNavigationUrls| and «[|elementName|, |attrName|]» matches an entry in the - [=navigating URL attributes list=], and if |attribute|'s [=protocol=] is + [=built-in navigating URL attributes list=], and if |attribute|'s [=protocol=] is "`javascript:`": 1. Then remove |attribute| from |child|. @@ -703,26 +710,17 @@ regard to order: ## Defaults ## {#sanitization-defaults} -There are four builtins: +There are three builtins: * The [=built-in safe default configuration=], -* the [=built-in unsafe default configuration=], * the [=built-in safe baseline configuration=], and -* the [=navigating URL attributes list=]. - -The built-in safe default configuration is the same as the [=built-in safe baseline configuration=]. - -ISSUE(233): Determine if this actually holds. - +* the [=built-in navigating URL attributes list=]. -The built-in unsafe default configuration is meant to allow anything. -It is as follows: +The built-in safe default configuration is as follows: ``` { - allow: [], - removeElements: [], - attributes: [], - removeAttributes: [], + elements: [ ... ], + attributes: [ ... ], } ``` @@ -739,7 +737,7 @@ script-content, and nothing else. It is as follows: ```
-The navigating URL attributes list, for which "`javascript:`" +The built-in navigating URL attributes list, for which "`javascript:`" navigations are "unsafe", are as follows: «[ From 88a3af09b5ca9427499b8315a6a8b63e4ec7ac3f Mon Sep 17 00:00:00 2001 From: Daniel Vogelheim Date: Fri, 29 Nov 2024 16:03:43 +0100 Subject: [PATCH 3/6] Split up SetHTMLOptions into safe / unsafe. Also make constructor take presets. --- index.bs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/index.bs b/index.bs index de2323a..50dffd6 100644 --- a/index.bs +++ b/index.bs @@ -121,7 +121,7 @@ markup, and an optional configuration.
 partial interface Element {
-  [CEReactions] undefined setHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLOptions options = {});
+  [CEReactions] undefined setHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLUnsafeOptions options = {});
   [CEReactions] undefined setHTML(DOMString html, optional SetHTMLOptions options = {});
 };
 
@@ -148,7 +148,7 @@ partial interface Element {
 partial interface ShadowRoot {
-  [CEReactions] undefined setHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLOptions options = {});
+  [CEReactions] undefined setHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLUnsafeOptions options = {});
   [CEReactions] undefined setHTML(DOMString html, optional SetHTMLOptions options = {});
 };
 
@@ -178,7 +178,7 @@ The {{Document}} interface gains two new methods which parse an entire {{Documen
 partial interface Document {
-  static Document parseHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLOptions options = {});
+  static Document parseHTMLUnsafe((TrustedHTML or DOMString) html, optional SetHTMLUnsafeOptions options = {});
   static Document parseHTML(DOMString html, optional SetHTMLOptions options = {});
 };
 
@@ -226,6 +226,9 @@ enum SanitizerPresets { "default" }; dictionary SetHTMLOptions { (Sanitizer or SanitizerConfig or SanitizerPresets) sanitizer = "default"; }; +dictionary SetHTMLUnsafeOptions { + (Sanitizer or SanitizerConfig or SanitizerPresets) sanitizer = {}; +};
The {{Sanitizer}} configuration object encapsulates a filter configuration. @@ -243,7 +246,7 @@ It can also be modified directly.
 [Exposed=(Window,Worker)]
 interface Sanitizer {
-  constructor(optional SanitizerConfig configuration = {});
+  constructor(optional (SanitizerConfig or SanitizerPresets) configuration = "default");
 
   // Query configuration:
   SanitizerConfig get();
@@ -259,9 +262,6 @@ interface Sanitizer {
 
   // Remove markup that executes script. May modify multiple lists:
   undefined removeUnsafe();
-
-  // Create a Sanitizer instance using the built-in defaults.
-  [NewObject] static Sanitizer getDefault();
 };
 
@@ -271,6 +271,9 @@ A {{Sanitizer}} has an associated configuration, a {{ The constructor(|configuration|) method steps are: +1. If |configuration| is a {{SanitizerPresets}} [=string=], then: + 1. [=Assert=]: |configuration| [=is=] {{SanitizerPresets/default}}. + 1. Let |configuration| be the [=built-in safe default configuration=]. 1. Let |valid| be the return value of [=set a configuration|setting=] |configuration| on [=this=]. 1. If |valid| is false, then throw a {{TypeError}}. @@ -382,6 +385,9 @@ To set and filter HTML, given an {{Element}} or {{DocumentFragment}} To get a sanitizer instance from options from a [=dictionary=] |options|, do: +Note: This algorithm works for both {{SetHTMLOptions}} and + {{SetHTMLUnsafeOptions}}. They only differ in the defaults. + 1. Let |sanitizerSpec| be "{{SanitizerPresets/default}}". 1. If |options|["{{SetHTMLOptions/sanitizer}}"] [=map/exists=], then: 1. Let |sanitizerSpec| be |options|["{{SetHTMLOptions/sanitizer}}"] From 5cb1490a2799f54ee496d4456fb5a6455d142887 Mon Sep 17 00:00:00 2001 From: Daniel Vogelheim <30862698+otherdaniel@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:24:14 +0100 Subject: [PATCH 4/6] Update index.bs Co-authored-by: Anne van Kesteren --- index.bs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/index.bs b/index.bs index 50dffd6..5dd2ef3 100644 --- a/index.bs +++ b/index.bs @@ -319,11 +319,6 @@ update [=this=]'s [=Sanitizer/configuration=] with the result of calling [=remov on [=this=]'s [=Sanitizer/configuration=]. -
-The getDefault method steps are to return the -result of [=get a sanitizer instance from options=] with «[ "{{SetHTMLOptions/sanitizer}}" → "{{SanitizerPresets/default}}" ]» -
- ## The Configuration Dictionary ## {#config}

From 1c0ae4307bbf2dcbeef017755fed5b1bcbcdc049 Mon Sep 17 00:00:00 2001
From: Daniel Vogelheim <30862698+otherdaniel@users.noreply.github.com>
Date: Tue, 10 Dec 2024 15:24:22 +0100
Subject: [PATCH 5/6] Update index.bs

Co-authored-by: Anne van Kesteren 
---
 index.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index 5dd2ef3..9bc99a7 100644
--- a/index.bs
+++ b/index.bs
@@ -273,7 +273,7 @@ method steps are:
 
 1. If |configuration| is a {{SanitizerPresets}} [=string=], then:
     1. [=Assert=]: |configuration| [=is=] {{SanitizerPresets/default}}.
-    1. Let |configuration| be the [=built-in safe default configuration=].
+    1. Set |configuration| to the [=built-in safe default configuration=].
 1. Let |valid| be the return value of [=set a configuration|setting=] |configuration| on [=this=].
 1. If |valid| is false, then throw a {{TypeError}}.
 

From f267f671bb9708d42f722b24a3b4d2586966ae89 Mon Sep 17 00:00:00 2001
From: Daniel Vogelheim 
Date: Wed, 11 Dec 2024 17:00:00 +0100
Subject: [PATCH 6/6] Fix usage of Let/Set.

---
 index.bs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/index.bs b/index.bs
index 9bc99a7..e758d55 100644
--- a/index.bs
+++ b/index.bs
@@ -385,12 +385,12 @@ Note: This algorithm works for both {{SetHTMLOptions}} and
 
 1. Let |sanitizerSpec| be "{{SanitizerPresets/default}}".
 1. If |options|["{{SetHTMLOptions/sanitizer}}"] [=map/exists=], then:
-   1. Let |sanitizerSpec| be |options|["{{SetHTMLOptions/sanitizer}}"]
+   1. Set |sanitizerSpec| to |options|["{{SetHTMLOptions/sanitizer}}"]
 1. [=Assert=]: |sanitizerSpec| is either a {{Sanitizer}} instance,
    a [=string=] which is a {{SanitizerPresets}} member, or a [=dictionary=].
 1. If |sanitizerSpec| is a [=string=]:
    1. [=Assert=]: |sanitizerSpec| [=is=] "{{SanitizerPresets/default}}"
-   1. Let |sanitizerSpec| be the [=built-in safe default configuration=].
+   1. Set |sanitizerSpec| to the [=built-in safe default configuration=].
 1. [=Assert=]: |sanitizerSpec| is either a {{Sanitizer}} instance,
    or a [=dictionary=].
 1. If |sanitizerSpec| is a [=dictionary=]:
@@ -398,7 +398,7 @@ Note: This algorithm works for both {{SetHTMLOptions}} and
    1. Let |setConfigurationResult| be the result of [=set a configuration=]
       with |sanitizerSpec| on |sanitizer|.
    1. If |setConfigurationResult| is false, [=throw=] a {{TypeError}}.
-   1. Let |sanitizerSpec| be |sanitizer|.
+   1. Set |sanitizerSpec| to |sanitizer|.
 1. [=Assert=]: |sanitizerSpec| is a {{Sanitizer}} instance.
 1. Return |sanitizerSpec|.