Skip to content

Commit 414ddd5

Browse files
author
Zerline
committed
Attempt for a javascript-side sanitization. Based on DOMPurifier.
1 parent 6b56c15 commit 414ddd5

File tree

6 files changed

+44
-83
lines changed

6 files changed

+44
-83
lines changed

ipywidgets/widgets/util.py

-68
This file was deleted.

ipywidgets/widgets/widget_description.py

+1-13
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33

44
"""Contains the DOMWidget class"""
55

6-
from traitlets import Bool, Unicode, observe
6+
from traitlets import Bool, Unicode
77
from .widget import Widget, widget_serialization, register
88
from .trait_types import InstanceDict
99
from .widget_style import Style
1010
from .widget_core import CoreWidget
1111
from .domwidget import DOMWidget
12-
from .util import sanitize
1312

1413
@register
1514
class DescriptionStyle(Style, CoreWidget, Widget):
@@ -25,17 +24,6 @@ class DescriptionWidget(DOMWidget, CoreWidget):
2524
description_html = Bool(False, help="Accept HTML in the description.").tag(sync=True)
2625
style = InstanceDict(DescriptionStyle, help="Styling customizations").tag(sync=True, **widget_serialization)
2726

28-
@observe('description', 'description_html')
29-
def description_changed(self, change):
30-
if change.name == 'description' and not self.description_html:
31-
return
32-
if change.name == 'description_html' and not change.new:
33-
return
34-
if change.name == 'description':
35-
self.description = sanitize(change.new)
36-
else:
37-
self.description = sanitize(self.description)
38-
3927
def _repr_keys(self):
4028
for key in super()._repr_keys():
4129
# Exclude style if it had the default value

packages/controls/src/widget_bool.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ export class CheckboxView extends DescriptionView {
8080
}
8181
const description = this.model.get('description');
8282
if (this.model.get('description_html')) {
83-
this.descriptionSpan.innerHTML = description;
83+
this.descriptionSpan.innerHTML = this.model.widget_manager.description_sanitize(
84+
description
85+
);
8486
} else {
8587
this.descriptionSpan.textContent = description;
8688
}

packages/controls/src/widget_description.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ export class DescriptionView extends DOMWidgetView {
7575
this.label.style.display = 'none';
7676
} else {
7777
if (this.model.get('description_html')) {
78-
this.label.innerHTML = description;
78+
this.label.innerHTML = this.model.widget_manager.description_sanitize(
79+
description
80+
);
7981
} else {
8082
this.label.textContent = description;
8183
}

packages/html-manager/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@jupyterlab/rendermime-interfaces": "^2.0.1",
4747
"@lumino/widgets": "^1.11.1",
4848
"ajv": "^6.10.0",
49+
"dompurify": "^2",
4950
"jquery": "^3.1.1"
5051
},
5152
"devDependencies": {

packages/html-manager/src/htmlmanager.ts

+36
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,39 @@ import {
1111
RenderMimeRegistry,
1212
standardRendererFactories
1313
} from '@jupyterlab/rendermime';
14+
import DOMPurify from 'dompurify';
1415

1516
import { WidgetRenderer, WIDGET_MIMETYPE } from './output_renderers';
1617
import { WidgetModel, WidgetView, DOMWidgetView } from '@jupyter-widgets/base';
1718

19+
/**
20+
* Sanitize HTML-formatted descriptions.
21+
*/
22+
export function default_description_sanitize(html: string): string {
23+
let config = {
24+
ALLOWED_TAGS: [
25+
'a',
26+
'abbr',
27+
'b',
28+
'blockquote',
29+
'code',
30+
'em',
31+
'i',
32+
'img',
33+
'li',
34+
'ol',
35+
'strong',
36+
'style',
37+
'ul'
38+
],
39+
ALLOWED_ATTRIBUTES: ['href', 'media', 'src', 'title']
40+
};
41+
return DOMPurify.sanitize(
42+
DOMPurify(html, { FORBID_TAGS: ['script'], KEEP_CONTENT: false }),
43+
config
44+
);
45+
}
46+
1847
export class HTMLManager extends ManagerBase {
1948
constructor(options?: {
2049
loader?: (moduleName: string, moduleVersion: string) => Promise<any>;
@@ -112,6 +141,13 @@ export class HTMLManager extends ManagerBase {
112141
*/
113142
renderMime: RenderMimeRegistry;
114143

144+
/**
145+
* How to sanitize HTML-formatted descriptions.
146+
*/
147+
protected description_sanitize(html: string): string {
148+
return default_description_sanitize(html);
149+
}
150+
115151
/**
116152
* A loader for a given module name and module version, and returns a promise to a module
117153
*/

0 commit comments

Comments
 (0)