sanitize.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. const sanitizeHtml = require('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. return sanitizeHtml(input, {
  15. // Allow "replacement" tags (in the format <0>, <1>, <2>, etc) used by
  16. // react-i18next to allow for HTML insertion via the Trans component.
  17. // See: https://github.com/overleaf/developer-manual/blob/master/code/translations.md
  18. // Unfortunately the sanitizeHtml library does not accept regexes or a
  19. // function for the allowedTags option, so we are limited to a hard-coded
  20. // number of "replacement" tags.
  21. allowedTags: ['b', 'strong', 'a', 'code', ...range(10)],
  22. allowedAttributes: {
  23. a: ['href', 'class'],
  24. },
  25. textFilter(text) {
  26. // Block Angular XSS
  27. if (text === '{') return '&#123;'
  28. if (text === '}') return '&#125;'
  29. return text
  30. .replace(/\{\{/, '&#123;&#123;')
  31. .replace(/\}\}/, '&#125;&#125;')
  32. },
  33. })
  34. }
  35. /**
  36. * Generate a range of numbers as strings up to the given size
  37. *
  38. * @param {number} size Size of range
  39. * @returns {string[]}
  40. */
  41. function range(size) {
  42. return Array.from(Array(size).keys()).map(n => n.toString())
  43. }
  44. module.exports = { sanitize }