Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.3 KiB
84 lines
2.3 KiB
/** ! |
|
* Sanitize an HTML string |
|
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com |
|
* @param {String} str The HTML string to sanitize |
|
* @param {Boolean} nodes If true, returns HTML nodes instead of a string |
|
* @return {String|NodeList} The sanitized string or nodes |
|
*/ |
|
function cleanHTML(str, nodes) { |
|
/** |
|
* Convert the string to an HTML document |
|
* @return {Node} An HTML document |
|
*/ |
|
function stringToHTML() { |
|
const parser = new DOMParser(); |
|
const doc = parser.parseFromString(str, 'text/html'); |
|
return doc.body || document.createElement('body'); |
|
} |
|
|
|
/** |
|
* Remove <script> elements |
|
* @param {Node} html The HTML |
|
*/ |
|
function removeScripts(html) { |
|
const scripts = html.querySelectorAll('script'); |
|
for(const script of scripts) { |
|
script.remove(); |
|
} |
|
} |
|
|
|
/** |
|
* Check if the attribute is potentially dangerous |
|
* @param {String} name The attribute name |
|
* @param {String} value The attribute value |
|
* @return {Boolean} If true, the attribute is potentially dangerous |
|
*/ |
|
function isPossiblyDangerous(name, value) { |
|
const val = value.replace(/\s+/g, '').toLowerCase(); |
|
if(['src', 'href', 'xlink:href'].includes(name)) { |
|
if(val.includes('javascript:') || val.includes('data:')) return true; |
|
} |
|
if(name.startsWith('on')) return true; |
|
} |
|
|
|
/** |
|
* Remove potentially dangerous attributes from an element |
|
* @param {Node} elem The element |
|
*/ |
|
function removeAttributes(elem) { |
|
// Loop through each attribute |
|
// If it's dangerous, remove it |
|
const atts = elem.attributes; |
|
for(const {name, value} of atts) { |
|
if(!isPossiblyDangerous(name, value)) continue; |
|
elem.removeAttribute(name); |
|
} |
|
} |
|
|
|
/** |
|
* Remove dangerous stuff from the HTML document's nodes |
|
* @param {Node} html The HTML document |
|
*/ |
|
function clean(html) { |
|
const nodes = html.children; |
|
for(const node of nodes) { |
|
removeAttributes(node); |
|
clean(node); |
|
} |
|
} |
|
|
|
// Convert the string to HTML |
|
const html = stringToHTML(); |
|
|
|
// Sanitize it |
|
removeScripts(html); |
|
clean(html); |
|
|
|
// If the user wants HTML nodes back, return them |
|
// Otherwise, pass a sanitized string back |
|
return nodes ? html.childNodes : html.innerHTML; |
|
} |
|
|
|
(window).cleanHTML = cleanHTML; |
|
|
|
module.exports = cleanHTML;
|
|
|