Blog post

MyBB <= 1.8.20: From Stored XSS to RCE

Simon Scannell photo

Simon Scannell

Vulnerability Researcher


  • Security
This blog post shows how an attacker can take over any board hosted with MyBB prior to version 1.8.21 by sending a malicious private message to an administrator or by creating a malicious...


We discovered a Stored XSS vulnerability that occured due to a parsing error in posts and private messages in MyBB 1.8.20 and prior versions, as well as an authenticated Remote Code Execution vulnerability that can be exploited by administrators of a forum.

An attacker merely needs a user account on a target forum to send an admin a private message containing malicious JavaScript code, which exploits the RCE vulnerability. This leads to a full remote take over of a target board by an attacker, as soon as as an administrator who is at the same time authenticated in the backend context opens the malicious PM. No further user interaction is required. 

This gives an attacker full access to all user accounts, private threads and messages stored in the board’s database.

Technical Analysis

In the following, we analyze the security flaws that were partially detected with Static Code Analysis.

Stored XSS through [video] bbcode

MyBB has a 3 step process to parse and render threads, posts and private messages. This process’ purpose is to sanitize user input and render so called mycodes or bbcodes. Bbcodes are a simple way for forum users to embed for example images, links and videos in posts.

The following graphic demonstrates the usual execution flow of the MyBB rendering process:

The process begins by simply escaping all HTML tags and double quotes. It will then convert all [video] mycodes into <iframe> tags that embed videos from e.g. YouTube. The reason for video bbcodes being rendered in a single step is because they can be disabled by administrators (they are enabled by default). Finally, it will convert all other mycodes, such as [url][quote] and [email] into HTML markup. 
The fact that [video] bbcodes were converted to HTML markup in a different step than all other bbcodes lead to the idea that it might be possible to craft a [video] bbcode that results in HTML markup that contains other shortcodes in it’s attributes, such as: 

<iframe src="[url]http://onload=evilCode()[/url]"></iframe>

The idea is that MyBB will then replace the [url] bbcode within the iframe’s src with more HTML markup containing double quotes ("), thus corrupting the HTML and leading to an attribute injection.

The above example would then result in the following HTML markup after the third and final step of the processing:

<iframe src="<a href="http://onload=evilCode()">.."></iframe>

As can be seen, the src attribute of the iframe is then closed by the injected href attribute and it’s quote. This now leads to the onload event handler being injected into the <iframe> HTML tag.

Usually, it would not be possible to inject bbcodes within other bbcodes as regex filters are in place that prevent such attacks. However, the callback method that is reponsible for rendering [video] bbcodes calls urldecode() on the URL of the video that should be embedded (e.g. This is shown in the following code snippet:


1385    function mycode_parse_video($video, $url)
1386    {
1387        global $templates;
1389        if(empty($video) || empty($url))
1390            return "[video={$video}]{$url}[/video]";
1392        $parsed_url = @parse_url(urldecode($url));
1394        // [...]

The fact that the video URL is urldecoded allows to bypass the regex protection and inject a [url] bbcode as depicted above by URL encoding it. This then leads to an onload event handler being injected into the <iframe> tag. This event handler triggers as soon as the page within the iframe is loaded, thus no user interaction is required to trigger malicious JavaScript code.

RCE in Admin panel via File Write

Administrators of a MyBB forum can manage stylesheets of the active theme of their installation within the Admin Panel. They can also create new stylesheet files on the server and choose the filename.

An obvious File Write vulnerability would occur if an attacker in the role of an administrator account could simply create a new stylesheet file and call it for example shell.php. However, a quick investigation of the source code behind this functionality revealed that only the .css file extension was allowed:


263    foreach($theme['stylesheets']['stylesheet'] as $stylesheet) {
264        if(substr($stylesheet['attributes']['name'], -4) != ".css"){
265           continue;

What captured our attention was what happened after the extension had been checked. Instead of simply creating the stylesheet file in the file system, MyBB first stores the name of the stylesheet file, as well as the contents in the MySQL database powering the board. When we looked at the mybb_themestylesheets table and how it was structured, we noticed something interesting: the name column which stores the filename of a newly imported stylesheet is defined as a varchar column with a maximum of 30 characters.

Table definition of mybb_themestylesheets

1    MariaDB [mybb]> DESC mybb_themestylesheets;
2    +--------------+----------------------+------+-----+---------+----------------+
3    | Field        | Type                 | Null | Key | Default | Extra          |
4    +--------------+----------------------+------+-----+---------+----------------+
5    | sid          | int(10) unsigned     | NO   | PRI | NULL    | auto_increment | 
6    | name         | varchar(30)          | NO   |     |         |                |
7      [...]
8    | stylesheet   | longtext             | NO   |     | NULL    |                |
9      [...]
10   +--------------+----------------------+------+-----+---------+----------------+

We then noticed that the length of a stylesheet filename is not checked when imported through an XML file, resulting in attackers being able to trick MyBB into inserting a filename with more than the allowed 30 characters. MySQL’s default behavior on many systems is to then truncate the filename to 30 characters.

An attacker could abuse this behavior by setting a filename to for example aaaaaaaaaaaaaaaaaaaaaaaaaa.php.css. This filename is 34 characters long. Since it ends with the .css extension, it passes the security checks of MyBB. However, when that string is then inserted into the database, it is truncated to 30 characters and only aaaaaaaaaaaaaaaaaaaaaaaaaa.php remains stored in the database.

An attacker can then use the admin panel to generate the newly imported stylesheet files and write them to the file system. This would create a PHP shell within the cache directory.


2019/04/29Reported multiple vulnerabilities privately to the MyBB team.
2019/04/29MyBB acknowledges the vulnerabilies.
2019/06/10MyBB releases version 1.8.21 which includes patches for the vulnerabilities.


This blog post detailed an exploit chain that can be abused to take over any forum running MyBB prior to version 1.8.21. An attacker could have abused the XSS flaw to take over any forum account on a target forum or to directly try to create a shell on the target system via the File Write vulnerability by sending an administrator a private message on a target forum that contains malicious JavaScript code. Although MyBB has two seperate sessions for the front end and the backend session and an administrator might not always have an active backend session while reading the private message, an attacker can try multiple times, since no user interaction other than the targeted administrator opening the malicious private message is required.

Related Posts