Уже порядка 9 лет я занимаюсь web разработкой и не понаслышке знаю что такое XSS. Так сложилось что избавиться от него крайне сложно почти для любого сайта, где пользователи постят хоть какой-то контент и я собирал все возможные комбинации атак на клиентскую часть. Скрипт получился очень простой и производительный, он не только позволяет спокойно пропускать весь HTML от пользователя и выводить его безопасно, но и прекрасно обрабатывает такие неизвестные уязвимости как encoding mutations.
Помимо прочего я постарался и добавил возможность вычищать спрятанные в Base64(например, SVG) прослушки.
К сожалению, в последнее время очень многие уязвимости не работают из-за введения в браузер CORS и CSP. Сегодня я обнаружил что перестала работать глубинная base64 в SVG, когда можно было неограниченно в один графический векторный файл вкладывать бесконечное количество base64 со скриптами внутри так глубоко, что его не находили. Лет 5 назад c XSS был полный рай, но сейчас браузер бьет по рукам и уязвимостей становится все меньше и меньше.
Для данного скрипта уязвимости собирались порядка 7 лет и не публикую мануалы по взлому. Расписаны уязвимости внизу класса и, если вы умеете читать регулярные выражения, то c легкостью разберетесь в пошаговом ступенчатом фильтре и выясните что именно работает. Это самый полный список уязвимостей XSS и их комбинаций упакованный в RegExp.
Скрипт умеет чистить атрибуты и теги входного HTML, удалять мутации, а также погружаться в base64 убирать зловредный JavaScript там при этом восстанавливая работоспособность графики и стилей.
Исходный код на PHP:
Помимо прочего я постарался и добавил возможность вычищать спрятанные в Base64(например, SVG) прослушки.
К сожалению, в последнее время очень многие уязвимости не работают из-за введения в браузер CORS и CSP. Сегодня я обнаружил что перестала работать глубинная base64 в SVG, когда можно было неограниченно в один графический векторный файл вкладывать бесконечное количество base64 со скриптами внутри так глубоко, что его не находили. Лет 5 назад c XSS был полный рай, но сейчас браузер бьет по рукам и уязвимостей становится все меньше и меньше.
Для данного скрипта уязвимости собирались порядка 7 лет и не публикую мануалы по взлому. Расписаны уязвимости внизу класса и, если вы умеете читать регулярные выражения, то c легкостью разберетесь в пошаговом ступенчатом фильтре и выясните что именно работает. Это самый полный список уязвимостей XSS и их комбинаций упакованный в RegExp.
Скрипт умеет чистить атрибуты и теги входного HTML, удалять мутации, а также погружаться в base64 убирать зловредный JavaScript там при этом восстанавливая работоспособность графики и стилей.
Исходный код на PHP:
PHP:
<?php
/*
* Total XSS preventer class by Full-R
*
*/
final class xCleaner {
public static function clean( string $html ): string {
return self::cleanXSS(
preg_replace(
[
'/\s?<iframe[^>]*?>.*?<\/iframe>\s?/si',
'/\s?<style[^>]*?>.*?<\/style>\s?/si',
'/\s?<script[^>]*?>.*?<\/script>\s?/si',
'#\son\w*="[^"]+"#',
],
[
'',
'',
''
],
$html
)
);
}
protected static function hexToSymbols( string $s ): string {
return html_entity_decode($s, ENT_XML1, 'UTF-8');
}
protected static function escape( string $s, string $m = 'attr' ): string {
preg_match_all('/data:\w+\/([a-zA-Z]*);base64,(?!_#_#_)([^)\'"]*)/mi', $s, $b64, PREG_OFFSET_CAPTURE);
if( count( array_filter( $b64 ) ) > 0 ) {
switch( $m ) {
case 'attr':
$xclean = self::cleanXSS(
urldecode(
base64_decode(
$b64[ 2 ][ 0 ][ 0 ]
)
)
);
break;
case 'tag':
$xclean = self::cleanTagInnerXSS(
urldecode(
base64_decode(
$b64[ 2 ][ 0 ][ 0 ]
)
)
);
break;
}
return substr_replace(
$s,
'_#_#_'. base64_encode( $xclean ),
$b64[ 2 ][ 0 ][ 1 ],
strlen( $b64[ 2 ][ 0 ][ 0 ] )
);
}
else {
return $s;
}
}
protected static function cleanXSS( string $s ): string {
// base64 injection prevention
$st = self::escape( $s, 'attr' );
return preg_replace([
// JSON unicode
'/\\\\u?{?([a-f0-9]{4,}?)}?/mi', // [1] unicode JSON clean
// Data b64 safe
'/\*\w*\*/mi', // [2] unicode simple clean
// Malware payloads
'/:?e[\s]*x[\s]*p[\s]*r[\s]*e[\s]*s[\s]*s[\s]*i[\s]*o[\s]*n[\s]*(:|;|,)?\w*/mi', // [3] (:expression) evalution
'/l[\s]*i[\s]*v[\s]*e[\s]*s[\s]*c[\s]*r[\s]*i[\s]*p[\s]*t[\s]*(:|;|,)?\w*/mi', // [4] (livescript:) evalution
'/j[\s]*s[\s]*c[\s]*r[\s]*i[\s]*p[\s]*t[\s]*(:|;|,)?\w*/mi', // [5] (jscript:) evalution
'/j[\s]*a[\s]*v[\s]*a[\s]*s[\s]*c[\s]*r[\s]*i[\s]*p[\s]*t[\s]*(:|;|,)?\w*/mi', // [6] (javascript:) evalution
'/b[\s]*e[\s]*h[\s]*a[\s]*v[\s]*i[\s]*o[\s]*r[\s]*(:|;|,)?\w*/mi', // [7] (behavior:) evalution
'/v[\s]*b[\s]*s[\s]*c[\s]*r[\s]*i[\s]*p[\s]*t[\s]*(:|;|,)?\w*/mi', // [8] (vsbscript:) evalution
'/v[\s]*b[\s]*s[\s]*(:|;|,)?\w*/mi', // [9] (vbs:) evalution
'/e[\s]*c[\s]*m[\s]*a[\s]*s[\s]*c[\s]*r[\s]*i[\s]*p[\s]*t*(:|;|,)?\w*/mi', // [10] (ecmascript:) possible ES evalution
'/b[\s]*i[\s]*n[\s]*d[\s]*i[\s]*n[\s]*g*(:|;|,)?\w*/mi', // [11] (-binding) payload
'/\+\/v(8|9|\+|\/)?/mi', // [12] (UTF-7 mutation)
// Some entities
'/&{\w*}\w*/mi', // [13] html entites clenup
'/&#\d+;?/m', // [14] html entites clenup
// Script tag encoding mutation issue
'/\¼\/?\w*\¾\w*/mi', // [21] mutation KOI-8
'/\+ADw-\/?\w*\+AD4-\w*/mi', // [22] mutation old encodings
'/\/*?%00*?\//m',
// base64 escaped
'/_#_#_/mi', // [23] base64 escaped marker cleanup
],
// Replacements steps :: 23
['&#x$1;', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
str_ireplace(
['\u0', ':', '&tab;', '&newline;'],
['\0', ':', '', ''],
// U-HEX prepare step
self::hexToSymbols( $st ))
);
}
}
?>
Вложения
Последнее редактирование: