Summary
The HtmlGenerator
class is subject to potential cross-site scripting (XSS) attack through a parsed malformed Minecraft server MOTD.
Context
Minecraft server owners can set a so-called MOTD (Message of the Day) for their server that appears next to the server icon and below the server name on the multiplayer server list of a player's Minecraft client. The Minecraft server sends the MOTD in the description
property of the Status Response packet. The jgniecki/MinecraftMotdParser PHP library is able to parse the value of the description
property, which can be either a string or an array of text components. By utilizing the aforementioned HtmlGenerator
class, it is also able to transform the value into an HTML string that can be used to visualize the MOTD on a web page.
Details
The HtmlGenerator
iterates through objects of MotdItem
that are contained in an object of MotdItemCollection
to generate a HTML string. An attacker can make malicious inputs to the color
and text
properties of MotdItem
to inject own HTML into a web page during web page generation. For example by sending a malicious MOTD from a Minecraft server under their control that was queried and passed to the HtmlGenerator
.
This XSS vulnerability exists because the values of these properties are neither filtered nor escaped, as can be seen here:
|
$tags['span'][] = sprintf('color: %s;', $motdItem->getColor()); |
|
$value = sprintf($value, $motdItem->getText()); |
Proof of Concept
JavaScript code can be injected into the HtmlGenerator
by parsing either a string via TextParser
or an array via ArrayParser
. The following code examples demonstrate the vulnerability by triggering the alert dialog of the browser.
XSS via TextParser
<?php
use DevLancer\MinecraftMotdParser\Collection\MotdItemCollection;
use DevLancer\MinecraftMotdParser\Generator\HtmlGenerator;
use DevLancer\MinecraftMotdParser\Parser\TextParser;
$motdCollection = (new TextParser())->parse('<script>alert("XSS on page load")</script>', new MotdItemCollection());
echo (new HtmlGenerator())->generate($motdCollection);
XSS via ArrayParser
<?php
use DevLancer\MinecraftMotdParser\Collection\MotdItemCollection;
use DevLancer\MinecraftMotdParser\Generator\HtmlGenerator;
use DevLancer\MinecraftMotdParser\Parser\ArrayParser;
$motdCollection = (new ArrayParser())->parse([
[
'color' => '#" onmouseover="javascript:alert(\'XSS when mouse pointer enters the span element\')"',
'text' => 'Hover me',
],
[
'color' => '#000000',
'text' => '<script>alert("XSS on page load")</script>',
]
], new MotdItemCollection());
echo (new HtmlGenerator())->generate($motdCollection);
Impact
If the HtmlGenerator
class of this library is used, this XSS vulnerability can potentially affect:
- Players visiting Minecraft server list websites (of which there are several dozen online, written in PHP) that display the MOTD.
- Users visiting Minecraft server status websites to query information about a Minecraft server.
- Server owners managing their Minecraft server via a web interface that displays the MOTD, where the attack could be carried out by a malicious Minecraft server plugin that modifies the MOTD without the server owner's consent.
It is not clear if and which platforms depend on this library.
Remediation
I suggest converting all HTML special characters in the values of the color
and text
properties to HTML entities. The display of the HTML entities will still be correct in the browser, but the XSS vulnerability will be eliminated as the values will no longer be interpreted as HTML by the browser.
This could be achieved by introducing a new private escape
function in the HtmlGenerator
class:
private function escape(string $text): string
{
return htmlentities($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
This function should be called in the following two lines:
|
$tags['span'][] = sprintf('color: %s;', $motdItem->getColor()); |
Change to: $tags['span'][] = sprintf('color: %s;', $this->escape($motdItem->getColor()));
|
$value = sprintf($value, $motdItem->getText()); |
Change to: $value = sprintf($value, $this->escape($motdItem->getText()));
Disclosure Policy
The Krymo Software team is dedicated to working closely with the open source community and with projects that are affected by a vulnerability, in order to protect users and ensure a coordinated disclosure. When we identify a vulnerability in a project, we will report it by contacting the publicly-listed security contact for the project if one exists; otherwise we will attempt to contact the project maintainers directly.
If the project team responds and agrees the issue poses a security risk, we will work with the project security team or maintainers to communicate the vulnerability in detail, and agree on the process for public disclosure. Responsibility for developing and releasing a patch lies firmly with the project team, though we aim to facilitate this by providing detailed information about the vulnerability.
Our disclosure deadline for publicly disclosing a vulnerability is: 90 days after the first report to the project team.
We appreciate the hard work maintainers put into fixing vulnerabilities and understand that sometimes more time is required to properly address an issue. We want project maintainers to succeed and because of that we are always open to discuss our disclosure policy to fit your specific requirements, when warranted.
Summary
The
HtmlGenerator
class is subject to potential cross-site scripting (XSS) attack through a parsed malformed Minecraft server MOTD.Context
Minecraft server owners can set a so-called MOTD (Message of the Day) for their server that appears next to the server icon and below the server name on the multiplayer server list of a player's Minecraft client. The Minecraft server sends the MOTD in the
description
property of the Status Response packet. The jgniecki/MinecraftMotdParser PHP library is able to parse the value of thedescription
property, which can be either a string or an array of text components. By utilizing the aforementionedHtmlGenerator
class, it is also able to transform the value into an HTML string that can be used to visualize the MOTD on a web page.Details
The
HtmlGenerator
iterates through objects ofMotdItem
that are contained in an object ofMotdItemCollection
to generate a HTML string. An attacker can make malicious inputs to thecolor
andtext
properties ofMotdItem
to inject own HTML into a web page during web page generation. For example by sending a malicious MOTD from a Minecraft server under their control that was queried and passed to theHtmlGenerator
.This XSS vulnerability exists because the values of these properties are neither filtered nor escaped, as can be seen here:
MinecraftMotdParser/src/Generator/HtmlGenerator.php
Line 49 in 0412f68
MinecraftMotdParser/src/Generator/HtmlGenerator.php
Line 80 in 0412f68
Proof of Concept
JavaScript code can be injected into the
HtmlGenerator
by parsing either a string viaTextParser
or an array viaArrayParser
. The following code examples demonstrate the vulnerability by triggering the alert dialog of the browser.XSS via
TextParser
XSS via
ArrayParser
Impact
If the
HtmlGenerator
class of this library is used, this XSS vulnerability can potentially affect:It is not clear if and which platforms depend on this library.
Remediation
I suggest converting all HTML special characters in the values of the
color
andtext
properties to HTML entities. The display of the HTML entities will still be correct in the browser, but the XSS vulnerability will be eliminated as the values will no longer be interpreted as HTML by the browser.This could be achieved by introducing a new private
escape
function in theHtmlGenerator
class:This function should be called in the following two lines:
MinecraftMotdParser/src/Generator/HtmlGenerator.php
Line 49 in 0412f68
Change to:
$tags['span'][] = sprintf('color: %s;', $this->escape($motdItem->getColor()));
MinecraftMotdParser/src/Generator/HtmlGenerator.php
Line 80 in 0412f68
Change to:
$value = sprintf($value, $this->escape($motdItem->getText()));
Disclosure Policy
The Krymo Software team is dedicated to working closely with the open source community and with projects that are affected by a vulnerability, in order to protect users and ensure a coordinated disclosure. When we identify a vulnerability in a project, we will report it by contacting the publicly-listed security contact for the project if one exists; otherwise we will attempt to contact the project maintainers directly.
If the project team responds and agrees the issue poses a security risk, we will work with the project security team or maintainers to communicate the vulnerability in detail, and agree on the process for public disclosure. Responsibility for developing and releasing a patch lies firmly with the project team, though we aim to facilitate this by providing detailed information about the vulnerability.
Our disclosure deadline for publicly disclosing a vulnerability is: 90 days after the first report to the project team.
We appreciate the hard work maintainers put into fixing vulnerabilities and understand that sometimes more time is required to properly address an issue. We want project maintainers to succeed and because of that we are always open to discuss our disclosure policy to fit your specific requirements, when warranted.