Skip to content

Commit b2cd96a

Browse files
committed
add: sanitize src urls for embeds as well
1 parent 182644a commit b2cd96a

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ On the other hand, the `customTextWrapper` parser function provides the followin
161161
- `child`: The HTML string that specifies the child element
162162
- `value`: The value passed against the child element
163163

164+
164165
You can use the following customized JSON RTE Serializer code to convert your JSON RTE field data into HTML format.
165166

166167
```javascript
@@ -230,6 +231,60 @@ The resulting HTML data will look as follows:
230231
```HTML
231232
<p><social-embed url="https://twitter.com/Contentstack/status/1508911909038436365?cxt=HHwWmsC9-d_Y3fApAAAA"></social-embed></p><p>This <color data-color="red">is</color> text.</p>
232233
```
234+
<br>
235+
<br>
236+
237+
##### <p>You can pass the option `skipURLSanitization` as true to bypass the validation checks and sanitization for the src URLs of JSON element types - social embed and embed.</p>
238+
<div>By default, this option is set to false.</div>
239+
240+
#### Examples:
241+
242+
1. For the following JSON, with src url containing script tags
243+
```JSON
244+
{
245+
"type": "doc",
246+
"attrs": {},
247+
"children": [
248+
{
249+
"type": "social-embeds",
250+
"attrs": {
251+
"src": "https://www.youtube.com/watch?v=Gw7EqoOYC9A\"></iframe><script>alert(document.cookie)</script><iframe ",
252+
"width": 560,
253+
"height": 320
254+
},
255+
}
256+
]
257+
}
258+
```
259+
The resulting HTML:
260+
```HTML
261+
<iframe src="https://www.youtube.com/watch?v=Gw7EqoOYC9A" width="560" height="320" data-type="social-embeds" ></iframe>
262+
```
263+
264+
2. For any JSON containing src urls violating expected protocols, the src attribute will be removed when converted to HTML
265+
266+
```JSON
267+
{
268+
"type": "doc",
269+
"attrs": {},
270+
"children": [
271+
{
272+
"type": "social-embeds",
273+
"attrs": {
274+
"src": "www.youtube.com/watch?v=Gw7EqoOYC9A\">",
275+
"width": 560,
276+
"height": 320
277+
},
278+
}
279+
]
280+
}
281+
```
282+
The resulting HTML:
283+
```HTML
284+
<iframe width="560" height="320" data-type="social-embeds" ></iframe>
285+
```
286+
287+
<br>
233288

234289
### Convert HTML to JSON
235290

src/toRedactor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string
495495
figureStyles.fieldsEdited.push(figureStyles.caption)
496496
}
497497

498-
if (!options?.skipURLSanitization && jsonValue['type'] === 'social-embeds') {
498+
if (!options?.skipURLSanitization && (jsonValue['type'] === 'social-embeds' || jsonValue['type'] === 'embed')) {
499499
const sanitizedHTML = DOMPurify.sanitize(allattrs['src']);
500500

501501
const urlMatch = sanitizedHTML.match(/https?:\/\/[^\s"'<>()]+/);

test/expectedJson.ts

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,9 +2002,9 @@ export default {
20022002
},
20032003
"RT-360":{
20042004
"html": [
2005-
`<iframe src="https://www.youtube.com/watch?v=Gw7EqoOYC9A" width="560" height="320" data-type="social-embeds" ></iframe>`,
2006-
`<iframe width="560" height="320" data-type="social-embeds" ></iframe>`,
2007-
'<iframe width="560" height="320" data-type="social-embeds" ></iframe>',
2005+
`<iframe src="https://www.youtube.com/watch?v=Gw7EqoOYC9A" width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A\"></iframe>`,
2006+
`<iframe width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\"></iframe>`,
2007+
'<iframe width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\"></iframe>',
20082008
],
20092009
"json":
20102010
[
@@ -2026,6 +2026,24 @@ export default {
20262026
"text": ""
20272027
}
20282028
]
2029+
},
2030+
{
2031+
"uid": "d3c2ab78a5e547b082f95dc01123b0c1",
2032+
"type": "doc",
2033+
"_version": 11,
2034+
"attrs": {},
2035+
"children": [
2036+
{
2037+
"uid": "87fed1cc68ce435caa0f71d17788c618",
2038+
"type": "embed",
2039+
"attrs": {
2040+
"src": "https://www.youtube.com/watch?v=Gw7EqoOYC9A\"></iframe><script>alert(document.cookie)</script><iframe ",
2041+
"redactor-attributes": {
2042+
"allowfullscreen": true
2043+
}
2044+
}
2045+
}
2046+
]
20292047
}
20302048
],
20312049
"_version": 1
@@ -2048,7 +2066,25 @@ export default {
20482066
"text": ""
20492067
}
20502068
]
2051-
}
2069+
},
2070+
{
2071+
"uid": "d3c2ab78a5e547b082f95dc01123b0c1",
2072+
"type": "doc",
2073+
"_version": 11,
2074+
"attrs": {},
2075+
"children": [
2076+
{
2077+
"uid": "87fed1cc68ce435caa0f71d17788c618",
2078+
"type": "embed",
2079+
"attrs": {
2080+
"src": null,
2081+
"redactor-attributes": {
2082+
"allowfullscreen": true
2083+
}
2084+
}
2085+
}
2086+
]
2087+
}
20522088
],
20532089
"_version": 1
20542090
},
@@ -2070,7 +2106,25 @@ export default {
20702106
"text": ""
20712107
}
20722108
]
2073-
}
2109+
},
2110+
{
2111+
"uid": "d3c2ab78a5e547b082f95dc01123b0c1",
2112+
"type": "doc",
2113+
"_version": 11,
2114+
"attrs": {},
2115+
"children": [
2116+
{
2117+
"uid": "87fed1cc68ce435caa0f71d17788c618",
2118+
"type": "embed",
2119+
"attrs": {
2120+
"src": "www.youtube.com/embed/VD6xJq8NguY",
2121+
"redactor-attributes": {
2122+
"allowfullscreen": true
2123+
}
2124+
}
2125+
}
2126+
]
2127+
}
20742128
],
20752129
"_version": 1
20762130
}

0 commit comments

Comments
 (0)