From f9c972d8669e1c2b7efd66d639d1b401b3a21ed2 Mon Sep 17 00:00:00 2001 From: thisgun Date: Thu, 17 Apr 2025 16:04:01 +0900 Subject: [PATCH] =?UTF-8?q?[KVE-2025-0191]=20Stored=20XSS=20(bypass=20html?= =?UTF-8?q?=5Fpurify=20via=20Open=20Redirect)=20=EC=B7=A8=EC=95=BD?= =?UTF-8?q?=EC=A0=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common.lib.php | 4 ++++ plugin/htmlpurifier/extend.video.php | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/common.lib.php b/lib/common.lib.php index 7100a04c5..b78615bd4 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -685,6 +685,10 @@ function html_purifier($html) ) ); + // 커스텀 URI 필터 등록 + $def = $config->getDefinition('URI', true); // URI 정의 가져오기 + $def->addFilter(new HTMLPurifierContinueParamFilter(), $config); // 커스텀 필터 추가 + $purifier = new HTMLPurifier($config); return run_replace('html_purifier_result', $purifier->purify($html), $purifier, $html); diff --git a/plugin/htmlpurifier/extend.video.php b/plugin/htmlpurifier/extend.video.php index 5c8ec59d2..01ced51d3 100644 --- a/plugin/htmlpurifier/extend.video.php +++ b/plugin/htmlpurifier/extend.video.php @@ -77,4 +77,30 @@ if( !class_exists('HTMLPurifier_Filter_Iframevideo') ){ } } } +} + +if( !class_exists('HTMLPurifierContinueParamFilter') ){ + class HTMLPurifierContinueParamFilter extends HTMLPurifier_URIFilter + { + public $name = 'ContinueParamFilter'; + + public function filter(&$uri, $config, $context) + { + // 쿼리 파라미터 검사 + $query = $uri->query; + $path = $uri->path; + + if ($path && preg_match('#[\\\\/]logout#i', $path)) { + return false; + } + + if ($query) { + if (isset($query_params['continue'])) { + return false; + } + } + + return true; // 조건 통과 시 허용 + } + } } \ No newline at end of file