Skip to content
Prev Previous commit
Next Next commit
Don't render non HTTP links, images and quotes
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen authored and LukasReschke committed Jan 13, 2017
commit 1a7d713883ca11716c14e20d5df1ef4fa7bbcf64
48 changes: 47 additions & 1 deletion settings/js/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Handlebars.registerHelper('level', function() {

OC.Settings = OC.Settings || {};
OC.Settings.Apps = OC.Settings.Apps || {
markedOptions: {},

setupGroupsSelect: function($elements) {
OC.Settings.setupGroupsSelect($elements, {
placeholder: t('core', 'All')
Expand Down Expand Up @@ -187,7 +189,7 @@ OC.Settings.Apps = OC.Settings.Apps || {
}

// Parse markdown in app description
app.description = marked(app.description.trim());
app.description = marked(app.description.trim(), OC.Settings.Apps.markedOptions);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too confident in that myself. I'll also add https://github.com/cure53/DOMPurify as post-processing.


var html = template(app);
if (selector) {
Expand Down Expand Up @@ -636,6 +638,50 @@ OC.Settings.Apps = OC.Settings.Apps || {
* Initializes the apps list
*/
initialize: function($el) {

var renderer = new marked.Renderer();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really happy with having that code in the "initialize" function. This means that if somebody somehow manages to bypass the sanitization opening the apps page would be enough to insert it into the DOM. IMO that should happen on clicking the "Show description" action.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Especially since markedjs/marked#592 is not really increasing my confidence in this library at all.

renderer.link = function(href, title, text) {
try {
var prot = decodeURIComponent(unescape(href))
.replace(/[^\w:]/g, '')
.toLowerCase();
} catch (e) {
return '';
}

if (prot.indexOf('http:') !== 0 && prot.indexOf('https:') !== 0) {
return '';
}

var out = '<a href="' + href + '"';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also set noreferrer noopener here.

if (title) {
out += ' title="' + title + '"';
}
out += '>' + text + '</a>';
return out;
};
renderer.image = function(href, title, text) {
if (text) {
return text;
}
return title;
};
renderer.blockquote = function(quote) {
return quote;
};

OC.Settings.Apps.markedOptions = {
renderer: renderer,
gfm: false,
highlight: false,
tables: false,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
};

OC.Plugins.register('OCA.Search', OC.Settings.Apps.Search);
OC.Settings.Apps.loadCategories();
OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this));
Expand Down