mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 17:53:49 -05:00
22ee7d6da2
[web] scripts/translations: sanitize: double down on angular xss GitOrigin-RevId: d08deab392942e593e920e648118f0e196af1740
48 lines
1.4 KiB
JavaScript
48 lines
1.4 KiB
JavaScript
const sanitizeHtml = require('sanitize-html')
|
||
|
||
/**
|
||
* Sanitize a translation string to prevent injection attacks
|
||
*
|
||
* @param {string} input
|
||
* @returns {string}
|
||
*/
|
||
function sanitize(input) {
|
||
// Block Angular XSS
|
||
// Ticket: https://github.com/overleaf/issues/issues/4478
|
||
input = input.replace(/'/g, '’')
|
||
// Use left quote where (likely) appropriate.
|
||
input.replace(/ ’/g, ' ‘')
|
||
|
||
return sanitizeHtml(input, {
|
||
// Allow "replacement" tags (in the format <0>, <1>, <2>, etc) used by
|
||
// react-i18next to allow for HTML insertion via the Trans component.
|
||
// See: https://github.com/overleaf/developer-manual/blob/master/code/translations.md
|
||
// Unfortunately the sanitizeHtml library does not accept regexes or a
|
||
// function for the allowedTags option, so we are limited to a hard-coded
|
||
// number of "replacement" tags.
|
||
allowedTags: ['b', 'strong', 'a', 'code', ...range(10)],
|
||
allowedAttributes: {
|
||
a: ['href', 'class'],
|
||
},
|
||
textFilter(text) {
|
||
// Block Angular XSS
|
||
if (text === '{') return '{'
|
||
if (text === '}') return '}'
|
||
return text
|
||
.replace(/\{\{/, '{{')
|
||
.replace(/\}\}/, '}}')
|
||
},
|
||
})
|
||
}
|
||
|
||
/**
|
||
* Generate a range of numbers as strings up to the given size
|
||
*
|
||
* @param {number} size Size of range
|
||
* @returns {string[]}
|
||
*/
|
||
function range(size) {
|
||
return Array.from(Array(size).keys()).map(n => n.toString())
|
||
}
|
||
|
||
module.exports = { sanitize }
|