sanitize.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import sanitizeHtml from 'sanitize-html'
  2. /**
  3. * Sanitize a translation string to prevent injection attacks
  4. *
  5. * @param {string} input
  6. * @returns {string}
  7. */
  8. function sanitize(input) {
  9. // Block Angular XSS
  10. // Ticket: https://github.com/overleaf/issues/issues/4478
  11. input = input.replace(/'/g, '’')
  12. // Use left quote where (likely) appropriate.
  13. input.replace(/ ’/g, ' ‘')
  14. // Allow "replacement" tags (in the format <0>, <1>, <2>, etc) used by
  15. // react-i18next to allow for HTML insertion via the Trans component.
  16. // See: https://github.com/overleaf/developer-manual/blob/master/code/translations.md
  17. // The html parser of sanitize-html is only accepting ASCII alpha characters
  18. // at the start of HTML tags. So we need to replace these ahead of parsing
  19. // and restore them afterwards.
  20. input = input.replaceAll(/<([/]?[0-9])>/g, '&lt;$1&gt;')
  21. return (
  22. sanitizeHtml(input, {
  23. allowedTags: ['b', 'strong', 'a', 'code'],
  24. allowedAttributes: {
  25. a: ['href', 'class'],
  26. },
  27. textFilter(text) {
  28. // Block Angular XSS
  29. if (text === '{') return '&#123;'
  30. if (text === '}') return '&#125;'
  31. return text
  32. .replace(/\{\{/, '&#123;&#123;')
  33. .replace(/\}\}/, '&#125;&#125;')
  34. },
  35. })
  36. // Restore the escaping again.
  37. .replaceAll(/&lt;([/]?[0-9])&gt;/g, '<$1>')
  38. // Restore escaped standalone ampersands
  39. .replaceAll(/ &amp; /g, ' & ')
  40. )
  41. }
  42. export default { sanitize }