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

Introspection of Sanitizer configs (and default config). #80

Merged
merged 4 commits into from
Apr 21, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -130,26 +130,42 @@ handle additional, application-specific use cases.
SecureContext
] interface Sanitizer {
constructor(optional SanitizerConfig config = {});

DocumentFragment sanitize(SanitizerInput input);
DOMString sanitizeToString(SanitizerInput input);

SanitizerConfig config();
static SanitizerConfig defaultConfig();
mozfreddyb marked this conversation as resolved.
Show resolved Hide resolved
};
</pre>

* The <dfn constructor for=Sanitizer lt="Sanitizer(config)">
<code>new Sanitizer(<var>config</var>)</code></dfn> constructor steps
are to create a new Sanitizer instance, and to retains a copy of |config|
are to create a new Sanitizer instance, and to retain a copy of |config|
as its [=configuration object=].
* The <dfn method for=Sanitizer><code>sanitize(<var>input</var>)</code></dfn>
method steps are to return the result of running the [=sanitize=]
algorithm on |input|,
* The <dfn method for=Sanitizer><code>sanitizeToString(<var>input</var>)</code></dfn>
method steps are to return the result of running [=sanitizeToString=]
algorithm on |input|.
* The <dfn method for=Sanitizer><code>config()</code></dfn> method steps are
to return the result of running the [=query the sanitizer config=]
algorithm. It essentially returns a copy of the Sanitizer's
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this sentence be marked as non normative?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I solved this by removing the sentence, and instead adding an example which compares the two. That way, normativity is clear, and we gain a free example. :-)

[=configuration object=], with some degree of normalization.
* The value of the static
<dfn method for=Sanitizer><code>defaultConfig()</code></dfn> method steps
are to return the value of the [=default configuration=] object.

Example:
```js
// Replace an element's content from unsanitized input:
element.replaceChildren(new Sanitizer().sanitize(userControlledInput));

// defaultConfig() and new Sanitizer().config should be the same.
// (For illustration purposes only. There are better ways of implementing
// object equality in JavaScript.)
JSON.stringify(Sanitizer.defaultConfig()) == JSON.stringify(new Sanitizer().config()); // true
```

## Input Types ## {#inputs}
Expand Down Expand Up @@ -240,6 +256,32 @@ Examples:
new Sanitizer().sanitizeToString("abc <script>alert(1)</script> def");
```

A sanitizer's configuration can be queried using the
[=query the sanitizer config=] method.

Examples:
```js
// Does the default config allow script elements?
Sanitizer.defaultConfig().allowElements.includes("script") // false

// We found a Sanitizer instance. Does it have an allow-list configured?
const a_sanitizer = ...;
!!a_sanitizer.config().allowElements // true, if an allowElements list is configured

// If it does have an allow elements list, does it include the <div> element?
a_sanitizer.config().allowElements.includes("div") // true, if "div" is in allowElements.

// Note that the config attribute might do some normaliztion. E.g., it won't
// contain key/value pairs that are not declare in the IDL.
Object.keys(new Sanitizer({madeUpDictionaryKey: "Hello"}).config()) // []

// As a Sanitizer's config describes its operation, a new sanitizer with
// another instance's configuration should behave identically.
// (For illustration purposes only. It would make more sense to just use a directly.)
const a = /* ... a Sanitizer we found somewhere ... */;
const b = new Sanitizer(a.config()); // b should behave the same as a.
```

### Attribute Match Lists ### {#attr-match-list}

An <dfn>attribute match list</dfn> is a map of attribute names to element names,
Expand Down Expand Up @@ -384,6 +426,18 @@ To <dfn>handle funky elements</dfn> on a given |element|, run these steps:
1. Remove the `formaction` attribute from |element|.
</div>

<div algorithm="query the sanitizer config">
To <dfn>query the sanitizer config</dfn> of a given sanitizer instance,
run these steps:
1. Let |sanitizer| be the current Sanitizer.
2. Let |config| be |sanitizer|'s [=configuration object=], or the
[=default configuration=] if no [=configuration object=] was given.
3. Let |result| be a newly constructed SanitizerOptions dictionary.
4. For any non-empty member of |config| whose key is declared in
SanitizerOptions, copy the value to |result|.
5. Return |result|.
</div>

### The Effective Configuration ### {#configuration}

A Sanitizer is potentially complex, so we will define a helper
Expand Down