@json-editor/json-editor 2.15.3 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/CHANGELOG.md +4 -0
- package/dist/jsoneditor.js +1 -1
- package/dist/jsoneditor.js.LICENSE.txt +1 -1
- package/dist/nonmin/jsoneditor.js +19 -1
- package/dist/nonmin/jsoneditor.js.map +1 -1
- package/package.json +1 -1
- package/src/editor.js +14 -0
- package/src/editors/hidden.js +1 -0
- package/src/editors/multiselect.js +1 -0
- package/src/editors/string.js +2 -0
- package/src/editors/uuid.js +1 -0
- package/tests/codeceptjs/editors/purify_test.js +26 -0
- package/tests/docker-compose-local.yml +5 -0
- package/tests/pages/purify.html +66 -0
package/package.json
CHANGED
package/src/editor.js
CHANGED
|
@@ -521,6 +521,20 @@ export class AbstractEditor {
|
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
+
purify (val) {
|
|
525
|
+
if (typeof val !== 'string') {
|
|
526
|
+
return val
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (window.DOMPurify) {
|
|
530
|
+
val = window.DOMPurify.sanitize(val)
|
|
531
|
+
} else {
|
|
532
|
+
val = this.cleanText(val)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return val
|
|
536
|
+
}
|
|
537
|
+
|
|
524
538
|
getHeaderText (titleOnly) {
|
|
525
539
|
if (this.header_text) return this.header_text
|
|
526
540
|
else if (titleOnly) return this.translateProperty(this.schema.title)
|
package/src/editors/hidden.js
CHANGED
|
@@ -178,6 +178,7 @@ export class MultiSelectEditor extends AbstractEditor {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
sanitize (value) {
|
|
181
|
+
value = this.purify(value)
|
|
181
182
|
if (this.schema.items.type === 'boolean') return !!value
|
|
182
183
|
else if (this.schema.items.type === 'number') return 1 * value || 0
|
|
183
184
|
else if (this.schema.items.type === 'integer') return Math.floor(value * 1 || 0)
|
package/src/editors/string.js
CHANGED
|
@@ -18,6 +18,7 @@ export class StringEditor extends AbstractEditor {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
setValue (value, initial, fromTemplate) {
|
|
21
|
+
value = this.purify(value)
|
|
21
22
|
value = this.applyConstFilter(value)
|
|
22
23
|
|
|
23
24
|
if (this.template && !fromTemplate) return
|
|
@@ -362,6 +363,7 @@ export class StringEditor extends AbstractEditor {
|
|
|
362
363
|
* This is overridden in derivative editors
|
|
363
364
|
*/
|
|
364
365
|
sanitize (value) {
|
|
366
|
+
value = this.purify(value)
|
|
365
367
|
return value
|
|
366
368
|
}
|
|
367
369
|
|
package/src/editors/uuid.js
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('purify')
|
|
4
|
+
|
|
5
|
+
Scenario('Should @purify @optional XSS from direct input', async ({ I }) => {
|
|
6
|
+
I.amOnPage('purify.html')
|
|
7
|
+
I.waitForElement('[name="root[string]"]')
|
|
8
|
+
I.fillField('[name="root[string]"]', 'bla</script><script>alert(1)</script>')
|
|
9
|
+
I.pressKey('Tab')
|
|
10
|
+
I.wait(1)
|
|
11
|
+
I.click('.get-value')
|
|
12
|
+
I.wait(1)
|
|
13
|
+
I.waitForValue('#value', '{"string":"bla"}')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
Scenario('Should @purify @optional XSS from setValue() via textarea', async ({ I }) => {
|
|
17
|
+
I.amOnPage('purify.html')
|
|
18
|
+
I.waitForElement('#value')
|
|
19
|
+
I.fillField('#value', 'bla</script><script>alert(1)</script>')
|
|
20
|
+
I.pressKey('Tab')
|
|
21
|
+
I.click('.set-value')
|
|
22
|
+
I.wait(2)
|
|
23
|
+
I.click('.get-value')
|
|
24
|
+
I.wait(1)
|
|
25
|
+
I.waitForValue('#value', '{"string":"bla"}')
|
|
26
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>Purify</title>
|
|
6
|
+
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.3.1/dist/purify.min.js"></script>
|
|
7
|
+
<script src="../../dist/jsoneditor.js"></script>
|
|
8
|
+
<link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
|
|
9
|
+
<link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<div class="container">
|
|
14
|
+
<div id='editor-container'></div>
|
|
15
|
+
<label for="value">Value</label>
|
|
16
|
+
<textarea id="value" class="form-control value" rows="10"></textarea>
|
|
17
|
+
<button class="get-value btn btn-primary">Get Value</button>
|
|
18
|
+
<button class="set-value btn btn-secondary">Set Value</button>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
const editorContainer = document.querySelector('#editor-container')
|
|
23
|
+
const value = document.querySelector('#value');
|
|
24
|
+
const schema = {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"title": "Purify",
|
|
27
|
+
"properties": {
|
|
28
|
+
"string": {
|
|
29
|
+
"title": "string (StringEditor)",
|
|
30
|
+
"type": "string"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const editor = new JSONEditor(editorContainer, {
|
|
36
|
+
schema: schema,
|
|
37
|
+
theme: 'bootstrap4',
|
|
38
|
+
iconlib: 'fontawesome',
|
|
39
|
+
disable_properties: true,
|
|
40
|
+
disable_collapse: true,
|
|
41
|
+
disable_edit_json: true,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const getValueBtn = document.querySelector('.get-value')
|
|
45
|
+
const setValueBtn = document.querySelector('.set-value')
|
|
46
|
+
|
|
47
|
+
editor.on('change', function () {
|
|
48
|
+
value.value = JSON.stringify(editor.getValue())
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
getValueBtn.addEventListener('click', function () {
|
|
52
|
+
value.value = JSON.stringify(editor.getValue())
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
setValueBtn.addEventListener('click', function () {
|
|
56
|
+
try {
|
|
57
|
+
editor.setValue(JSON.parse(value.value))
|
|
58
|
+
} catch (e) {
|
|
59
|
+
editor.setValue({ string: value.value })
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
66
|
+
|