File CVE-2024-43805.patch of Package python-jupyterlab.18615
From 42507491730b57908cfe4f048c2f84b3b92243bf Mon Sep 17 00:00:00 2001
From: nkrapp <nico.krapp@suse.com>
Date: Fri, 6 Sep 2024 19:11:27 +0200
Subject: [PATCH] fix-cve-2024-43805
---
.../apputils-extension/schema/sanitizer.json | 25 +++++++++++
packages/apputils-extension/src/index.ts | 41 +++++++++++++++++++
packages/apputils/src/sanitizer.ts | 37 +++++++++++------
3 files changed, 91 insertions(+), 12 deletions(-)
create mode 100644 packages/apputils-extension/schema/sanitizer.json
diff --git a/packages/apputils-extension/schema/sanitizer.json b/packages/apputils-extension/schema/sanitizer.json
new file mode 100644
index 0000000000..36c28a3a4e
--- /dev/null
+++ b/packages/apputils-extension/schema/sanitizer.json
@@ -0,0 +1,25 @@
+{
+ "title": "HTML Sanitizer",
+ "description": "HTML Sanitizer settings.",
+ "jupyter.lab.setting-icon": "ui-components:html5",
+ "additionalProperties": false,
+ "properties": {
+ "allowedSchemes": {
+ "title": "Allowed URL Scheme",
+ "description": "Scheme allowed by the HTML sanitizer.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string"
+ },
+ "default": ["http", "https", "ftp", "mailto", "tel"]
+ },
+ "allowNamedProperties": {
+ "type": "boolean",
+ "title": "Allow named properties",
+ "description": "Whether to allow untrusted elements to include `name` and `id` attributes. These attributes are stripped by default to prevent DOM clobbering attacks.",
+ "default": false
+ }
+ },
+ "type": "object"
+}
diff --git a/packages/apputils-extension/src/index.ts b/packages/apputils-extension/src/index.ts
index 852c4232da..4fe2e9bd0c 100644
--- a/packages/apputils-extension/src/index.ts
+++ b/packages/apputils-extension/src/index.ts
@@ -485,6 +485,47 @@ const utilityCommands: JupyterFrontEndPlugin<void> = {
}
};
+/**
+ * The default HTML sanitizer.
+ */
+const sanitizer: JupyterFrontEndPlugin<ISanitizer> = {
+ id: '@jupyter/apputils-extension:sanitizer',
+ autoStart: true,
+ provides: ISanitizer,
+ requires: [ISettingRegistry],
+ activate: (app: JupyterFrontEnd, settings: ISettingRegistry): ISanitizer => {
+ const sanitizer = new Sanitizer();
+ const loadSetting = (setting: ISettingRegistry.ISettings): void => {
+ const allowedSchemes = setting.get('allowedSchemes').composite as Array<
+ string
+ >;
+ const allowNamedProperties = setting.get('allowNamedProperties')
+ .composite as boolean;
+
+ if (allowedSchemes) {
+ sanitizer.setAllowedSchemes(allowedSchemes);
+ }
+
+ sanitizer.setAllowNamedProperties(allowNamedProperties);
+ };
+
+ // Wait for the application to be restored and
+ // for the settings for this plugin to be loaded
+ settings
+ .load('@jupyterlab/apputils-extension:sanitizer')
+ .then(setting => {
+ // Read the settings
+ loadSetting(setting);
+ // Listen for your plugin setting changes using Signal
+ setting.changed.connect(loadSetting);
+ })
+ .catch(reason => {
+ console.error(`Failed to load sanitizer settings:`, reason);
+ });
+ return sanitizer;
+ }
+};
+
/**
* Export the plugins as default.
*/
diff --git a/packages/apputils/src/sanitizer.ts b/packages/apputils/src/sanitizer.ts
index 7b479273c7..9f10518a1e 100644
--- a/packages/apputils/src/sanitizer.ts
+++ b/packages/apputils/src/sanitizer.ts
@@ -451,6 +451,9 @@ class CssProp {
* A class to sanitize HTML strings.
*/
class Sanitizer implements ISanitizer {
+ constructor() {
+ this._options = this._generateOptions();
+ }
/**
* Sanitize an HTML string.
*
@@ -464,7 +467,17 @@ class Sanitizer implements ISanitizer {
return sanitize(dirty, { ...this._options, ...(options || {}) });
}
- private _options: sanitize.IOptions = {
+ /**
+ * Set the whether to allow `name` and `id` attributes.
+ */
+ setAllowNamedProperties(allowNamedProperties: boolean): void {
+ this._allowNamedProperties = allowNamedProperties;
+ this._options = this._generateOptions();
+ }
+
+ private _allowNamedProperties: boolean = false;
+ private _options: sanitize.IOptions;
+ private _generateOptions = (): sanitize.IOptions => ({
// HTML tags that are allowed to be used. Tags were extracted from Google Caja
allowedTags: [
'a',
@@ -579,7 +592,7 @@ class Sanitizer implements ISanitizer {
'dir',
'draggable',
'hidden',
- 'id',
+ ...(this._allowNamedProperties ? ['id'] : []),
'inert',
'itemprop',
'itemref',
@@ -596,7 +609,7 @@ class Sanitizer implements ISanitizer {
'coords',
'href',
'hreflang',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'rel',
'shape',
'tabindex',
@@ -625,7 +638,7 @@ class Sanitizer implements ISanitizer {
bdo: ['dir'],
blockquote: ['cite'],
br: ['clear'],
- button: ['accesskey', 'disabled', 'name', 'tabindex', 'type', 'value'],
+ button: ['accesskey', 'disabled', ...(this._allowNamedProperties ? ['name'] : []), 'tabindex', 'type', 'value'],
canvas: ['height', 'width'],
caption: ['align'],
col: ['align', 'char', 'charoff', 'span', 'valign', 'width'],
@@ -652,7 +665,7 @@ class Sanitizer implements ISanitizer {
'autocomplete',
'enctype',
'method',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'novalidate'
],
h1: ['align'],
@@ -677,7 +690,7 @@ class Sanitizer implements ISanitizer {
'height',
'hspace',
'ismap',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'src',
'usemap',
'vspace',
@@ -698,7 +711,7 @@ class Sanitizer implements ISanitizer {
'maxlength',
'min',
'multiple',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'placeholder',
'readonly',
'required',
@@ -714,13 +727,13 @@ class Sanitizer implements ISanitizer {
label: ['accesskey', 'for'],
legend: ['accesskey', 'align'],
li: ['type', 'value'],
- map: ['name'],
+ map: this._allowNamedProperties ? ['name'] : [],
menu: ['compact', 'label', 'type'],
meter: ['high', 'low', 'max', 'min', 'value'],
ol: ['compact', 'reversed', 'start', 'type'],
optgroup: ['disabled', 'label'],
option: ['disabled', 'label', 'selected', 'value'],
- output: ['for', 'name'],
+ output: ['for', ...(this._allowNamedProperties ? ['name'] : [])],
p: ['align'],
pre: ['width'],
progress: ['max', 'min', 'value'],
@@ -729,7 +742,7 @@ class Sanitizer implements ISanitizer {
'autocomplete',
'disabled',
'multiple',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'required',
'size',
'tabindex'
@@ -769,7 +782,7 @@ class Sanitizer implements ISanitizer {
'cols',
'disabled',
'inputmode',
- 'name',
+ ...(this._allowNamedProperties ? ['name'] : []),
'placeholder',
'readonly',
'required',
@@ -961,7 +974,7 @@ class Sanitizer implements ISanitizer {
// Since embedded data is no longer deemed to be a threat, validation can be skipped.
// See https://github.com/jupyterlab/jupyterlab/issues/5183
allowedSchemesAppliedToAttributes: ['href', 'cite']
- };
+ });
}
/**
--
2.46.0