Пример POC с других сайтов: https://laworigin.github.io/2018/04/22/Discuz-x-portal-Stored-XSS-CVE-2018-10298/
При тестировании исправлений я заметил, что редактор портала Discuz! X отличается от редактора форума. Система автоматически отправляет HTML-код, поэтому простое экранирование недостаточно для защиты от XSS (хотя POC упоминает использование экранирования, это не работает, так как в этом случае весь портал будет содержать HTML-код...).
Учитывая серьезность угрозы при хранении XSS, я рассматривал возможность использования фильтрации для исправления, но поскольку портал позволяет вводить прямой HTML, такое исправление может повлиять на публикацию частей с особыми кодами.
Вот пример подхода через фильтрацию. Конечно, я также надеюсь услышать предложения от экспертов, которые могут предложить лучшие решения для внедрения в основной код.
function getstr($string, $length = 0, $in_slashes = 0, $out_slashes = 0, $bbcode = 0, $html = 0) {
global $_G;
$string = trim($string);
$sppos = strpos($string, chr(0).chr(0).chr(0));
if ($sppos !== false) {
$string = substr($string, 0, $sppos);
}
if ($in_slashes) {
$string = dstripslashes($string);
}
$string = preg_replace("/\[hide=?\d*\](.*?)\[\/hide\]/is", '', $string);
if ($html < 0) {
$string = preg_replace("/(\<[^\<]*\>|\r|\n|\s|\[.+?\])/is", ' ', $string);
$string = getstr_remove_xss($string); // Добавленный код, вызывает следующую функцию
} elseif ($html == 0) {
$string = dhtmlspecialchars($string);
}
if ($length) {
$string = cutstr($string, $length);
}
}
``````php
if ($bbcode) {
require_once DISCUZ_ROOT . '/source/class/class_bbcode.php';
$bb = &bbcode::instance();
$string = $bb->bbcode2html($string, $bbcode);
}
if ($out_slashes) {
$string = daddslashes($string);
}
return trim($string);
}
```php
function getstr_remove_xss($string) { // Добавленный фильтрационный функционал, который фильтрует атрибуты onxx в HTML-тегах
$parm = array(
'onabort',
'onactivate',
'onafterprint',
'onafterupdate',
'onbeforeactivate',
'onbeforecopy',
'onbeforecut',
'onbeforedeactivate',
'onbeforeeditfocus',
'onbeforepaste',
'onbeforeprint',
'onbeforeunload',
'onbeforeupdate',
'onblur',
'onbounce',
'oncellchange',
'onchange',
'onclick',
'oncontextmenu',
'oncontrolselect',
'oncopy',
'oncut',
'ondataavailable',
'ondatasetchanged',
'ondatasetcomplete',
'ondblclick',
'ondeactivate',
'ondrag',
'ondragend',
'ondragenter',
'ondragleave',
'ondragover',
'ondragstart',
'ondrop',
'onerror',
'onerrorupdate',
'onfilterchange',
'onfinish',
'onfocus',
'onfocusin',
'onfocusout',
'onhelp',
'onkeydown',
'onkeypress',
'onkeyup',
'onlayoutcomplete',
'onload',
'onlosecapture',
'onmousedown',
'onmouseenter',
'onmouseleave',
'onmousemove',
'onmouseout',
'onmouseover',
'onmouseup',
'onmousewheel',
'onmove',
'onmoveend',
'onmovestart',
'onpaste',
'onpropertychange',
'onreadystatechange',
'onreset',
'onresize',
'onresizeend',
'onresizestart',
'onrowenter',
'onrowexit',
'onrowsdelete',
'onrowsinserted',
'onscroll',
'onselect',
'onselectionchange',
'onselectstart',
'onstart',
'onstop',
'onsubmit',
'onunload'
);
for ($i = 0; $i < count($parm); $i++) {
$pattern = '/' . str_replace('/', '\\/', $parm[$i]) . '(=("[^"]*"|\'[^']*\'|[^\\\]\'\]*)?)|(\'[^\']*\')|("[^"]*"))/';
$string = preg_replace_callback($pattern, function ($matches) use ($parm) {
foreach ($parm as $attr) {
if (!empty($matches[1])) {
return $matches[1];
} elseif (!empty($matches[2])) {
return $matches[2];
} elseif (!empty($matches[3])) {
return $matches[3];
}
}
return '';
}, $string);
}
return $string;
}
``````php
if ($j > 0) {
$pattern .= '(';
$pattern .= '(&#[x|X]0([9][a][b]);? )? ';
$pattern .= '|(�([9][10][13]);? )? ';
$pattern .= ')? ';
}
$pattern .= $parm[$i][$j];
}
$pattern .= '/i';
$string = preg_replace($pattern, ' ', $string);
}
return $string;
}
Пожалуйста, предоставьте текст для перевода. В текущем виде запрос не содержит текста для перевода.