diff --git a/services/web/app/views/project/editor/chat.pug b/services/web/app/views/project/editor/chat.pug index a560f81724..e9460d9e78 100644 --- a/services/web/app/views/project/editor/chat.pug +++ b/services/web/app/views/project/editor/chat.pug @@ -41,6 +41,7 @@ aside.chat( .message-content p( mathjax, + mathjax-allow-html="true", ng-repeat="content in message.contents track by $index" ) span(ng-bind-html="content | linky:'_blank':{rel: 'noreferrer noopener'}") diff --git a/services/web/public/src/directives/mathjax.js b/services/web/public/src/directives/mathjax.js index 854b44a578..96bbf4eab4 100644 --- a/services/web/public/src/directives/mathjax.js +++ b/services/web/public/src/directives/mathjax.js @@ -1,15 +1,19 @@ /* global MathJax, _ */ define(['base'], function(App) { - return App.directive('mathjax', function($compile) { + return App.directive('mathjax', function($compile, $parse) { return { link(scope, element, attrs) { if (!(MathJax && MathJax.Hub)) return - const mathJaxContents = element.html() - const nonBindableEl = $compile('')({}) - element.html('').append(nonBindableEl) - nonBindableEl.html(mathJaxContents) + // Allowing HTML can be unsafe unless using something like + // `ng-bind-html` because of potential Angular XSS via {{/}} + if (!$parse(attrs.mathjaxAllowHtml)(scope)) { + const mathJaxContents = element.html() + const nonBindableEl = $compile('')({}) + element.html('').append(nonBindableEl) + nonBindableEl.html(mathJaxContents) + } if (attrs.delimiter !== 'no-single-dollar') { const inlineMathConfig =