Private GIT

Skip to content
Snippets Groups Projects
Unverified Commit c1a610bb authored by Gary Allan's avatar Gary Allan
Browse files

Bugfix: Stored XSS in instructions widgets. Fixes #3025

parent ae215951
No related branches found
No related tags found
No related merge requests found
...@@ -23,7 +23,7 @@ $User->check_maintaneance_mode (); ...@@ -23,7 +23,7 @@ $User->check_maintaneance_mode ();
$User->Crypto->csrf_cookie ("validate", "instructions", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : ""; $User->Crypto->csrf_cookie ("validate", "instructions", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : "";
# strip script # strip script
$_POST['instructions'] = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $_POST['instructions']); $_POST['instructions'] = $User->noxss_html($_POST['instructions']);
# validate ID # validate ID
if ($_POST['id']=="1" || $_POST['id']=="2") { if ($_POST['id']=="1" || $_POST['id']=="2") {
......
...@@ -13,7 +13,7 @@ $User->check_user_session(); ...@@ -13,7 +13,7 @@ $User->check_user_session();
// vaidate cookie // vaidate cookie
$User->Crypto->csrf_cookie ("validate", "instructions", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : ""; $User->Crypto->csrf_cookie ("validate", "instructions", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : "";
// strip script // strip script
$_POST['instructions'] = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $_POST['instructions']); $_POST['instructions'] = $User->noxss_html($_POST['instructions']);
?> ?>
<div class="normalTable" style="padding: 5px;"> <div class="normalTable" style="padding: 5px;">
......
...@@ -189,8 +189,7 @@ if(is_object($instructions)) { ...@@ -189,8 +189,7 @@ if(is_object($instructions)) {
$instructions->instructions = stripslashes($instructions->instructions); //show html $instructions->instructions = stripslashes($instructions->instructions); //show html
/* prevent <script> */ /* prevent <script> */
$instructions->instructions = str_replace("<script", "<div class='error'><xmp><script", $instructions->instructions); $instructions->instructions = $User->noxss_html($instructions->instructions);
$instructions->instructions = str_replace("</script>", "</script></xmp></div>", $instructions->instructions);
print "<div id='login' class='request'>"; print "<div id='login' class='request'>";
print "<div class='requestIP'>"; print "<div class='requestIP'>";
......
...@@ -12,8 +12,7 @@ $instructions = $instructions->instructions; ...@@ -12,8 +12,7 @@ $instructions = $instructions->instructions;
$instructions = stripslashes($instructions); //show html $instructions = stripslashes($instructions); //show html
/* prevent <script> */ /* prevent <script> */
$instructions = str_replace("<script", "<div class='error'><xmp><script", $instructions); $instructions = $Tools->noxss_html($instructions);
$instructions = str_replace("</script>", "</script></xmp></div>", $instructions);
// HSS header // HSS header
header('X-XSS-Protection:1; mode=block'); header('X-XSS-Protection:1; mode=block');
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
# Required extensions # Required extensions
$requiredExt = array("session", "sockets", "filter", "openssl", "gmp", "json", "gettext", "PDO", "pdo_mysql", "mbstring", "gd", "iconv", "ctype", "curl"); $requiredExt = array("session", "sockets", "filter", "openssl", "gmp", "json", "gettext", "PDO", "pdo_mysql", "mbstring", "gd", "iconv", "ctype", "curl", "dom");
# Available extensions # Available extensions
$availableExt = get_loaded_extensions(); $availableExt = get_loaded_extensions();
......
...@@ -619,6 +619,60 @@ class Common_functions { ...@@ -619,6 +619,60 @@ class Common_functions {
return is_null($input) ? NULL : strip_tags($input); return is_null($input) ? NULL : strip_tags($input);
} }
/**
* Remove <script>, <iframe> and JS HTML event attributes from HTML to protect from XSS
*
* @param string $html
* @return string
*/
public function noxss_html($html) {
if (!is_string($html) || strlen($html)==0)
return "";
try {
$dom = new \DOMDocument();
if ($dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOBLANKS | LIBXML_NOWARNING | LIBXML_NOERROR) === false)
return "";
$banned_elements = ['script', 'iframe', 'embed'];
$remove_elemets = [];
$elements = $dom->getElementsByTagName('*');
if (!is_object($elements) || $elements->length==0)
return $html; // no HTML elements
foreach($elements as $e) {
if (in_array($e->nodeName, $banned_elements)) {
$remove_elemets[] = $e;
continue;
}
if (!$e->hasAttributes())
continue;
// remove on* HTML event attributes
foreach ($e->attributes as $attr) {
if (substr($attr->nodeName,0,2) == "on")
$e->removeAttribute($attr->nodeName);
}
}
// Remove banned elements
foreach($remove_elemets as $e)
$e->parentNode->removeChild($e);
// Return sanitised HTML
$html = $dom->saveHTML();
return is_string($html) ? $html : "";
} catch (Exception $e) {
return "";
}
}
/** /**
* Changes empty array fields to specified character * Changes empty array fields to specified character
* *
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
+ SQL injections processing `ftype` (#2751); + SQL injections processing `ftype` (#2751);
+ All circuits map, PHP object injection (#2937); + All circuits map, PHP object injection (#2937);
+ Upgraded jQuery to 3.5.1 (#3119); + Upgraded jQuery to 3.5.1 (#3119);
+ Stored XSS in instructions widgets (#3025);
Translations: Translations:
---------------------------- ----------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment