2022-02-02 05:24:08 -05:00
|
|
|
|
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, ' ‘')
|
|
|
|
|
|
2022-05-17 04:37:25 -04:00
|
|
|
|
// 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
|
|
|
|
|
// The html parser of sanitize-html is only accepting ASCII alpha characters
|
|
|
|
|
// at the start of HTML tags. So we need to replace these ahead of parsing
|
|
|
|
|
// and restore them afterwards.
|
|
|
|
|
input = input.replaceAll(/<([/]?[0-9])>/g, '<$1>')
|
2022-02-02 05:24:08 -05:00
|
|
|
|
|
2022-05-17 04:37:25 -04:00
|
|
|
|
return (
|
|
|
|
|
sanitizeHtml(input, {
|
|
|
|
|
allowedTags: ['b', 'strong', 'a', 'code'],
|
|
|
|
|
allowedAttributes: {
|
|
|
|
|
a: ['href', 'class'],
|
|
|
|
|
},
|
|
|
|
|
textFilter(text) {
|
|
|
|
|
// Block Angular XSS
|
|
|
|
|
if (text === '{') return '{'
|
|
|
|
|
if (text === '}') return '}'
|
|
|
|
|
return text
|
|
|
|
|
.replace(/\{\{/, '{{')
|
|
|
|
|
.replace(/\}\}/, '}}')
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
// Restore the escaping again.
|
|
|
|
|
.replaceAll(/<([/]?[0-9])>/g, '<$1>')
|
2023-10-23 06:24:11 -04:00
|
|
|
|
// Restore escaped standalone ampersands
|
|
|
|
|
.replaceAll(/ & /g, ' & ')
|
2022-05-17 04:37:25 -04:00
|
|
|
|
)
|
2022-02-02 05:24:08 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = { sanitize }
|