Table of Contents
Introduction #
본 취약점은 그누보드 (Gnuboard) 5.6.15 버전의 댓글 조회 기능에서 발생한, CSS injection을 통한 reflected XSS가 가능한 취약점이다[1, 2].
Root-cause Analylsis #
그누보드 게시판에서 댓글을 조회할 때 c_id를 GET 요청의 파라미터로 전달한다. 이 파라미터는 다음과 같이 XSS 필터링을 거친다 (bbs/view_comment.php에서 발췌)[5].
$c_id= isset($_GET['c_id']) ? clean_xss_tags($_GET['c_id'], 1, 1) : '';
그리고 clean_xss_tags 함수는 다음과 같이 구현되어 있다 (lib/common.lib.php에서 발췌)[5].
// XSS 관련 태그 제거
function clean_xss_tags($str, $check_entities=0, $is_remove_tags=0, $cur_str_len=0, $is_trim_both=1)
{
if( $is_trim_both ) {
// tab('\t'), formfeed('\f'), vertical tab('\v'), newline('\n'), carriage return('\r') 를 제거한다.
$str = preg_replace("#[\t\f\v\n\r]#", '', $str);
}
if( $is_remove_tags ){
$str = strip_tags($str);
}
if( $cur_str_len ){
$str = utf8_strcut($str, $cur_str_len, '');
}
$str_len = strlen($str);
$i = 0;
while($i <= $str_len){
$result = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $str);
if( $check_entities ){
$result = str_replace(array(':', '(', ')', '
', '	'), '', $result);
}
$result = preg_replace('#([^\p{L}]|^)(?:javascript|jar|applescript|vbscript|vbs|wscript|jscript|behavior|mocha|livescript|view-source)\s*:(?:.*?([/\\\;()\'">]|$))#ius',
'$1$2', $result);
if((string)$result === (string)$str) break;
$str = $result;
$i++;
}
return $str;
}
위 구현들을 보면 따옴표나 CSS와 이벤트 관련 속성에 대한 필터링이 충분하지 않음을 알 수 있다.
이렇게 처리된 c_id는 다음과 같이 사용자 브라우저에 표시된다 (skin/board/basic/view_comment_skin.php에서 발췌)[5].
<!-- 댓글 쓰기 시작 { -->
<aside id="bo_vc_w" class="bo_vc_w">
<h2>댓글쓰기</h2>
<form name="fviewcomment" id="fviewcomment" action="<?php echo $comment_action_url; ?>" onsubmit="return fviewcomment_submit(this);" method="post" autocomplete="off">
<!-- ... -->
<input type="hidden" name="comment_id" value="<?php echo $c_id ?>" id="comment_id">
이것으로 CSS injection을 통한 reflected XSS를 할 수 있다.
Proof-of-Concept #
kinugawamasato님은 input 태그의 type 속성이 hidden일 때 CSS injection으로 XSS를 하는 방법을 소개했다. 이는 여기에 그대로 적용 가능하다. 그 페이로드는 다음과 같다[4].
http://localhost:12345/bbs/board.php?bo_table=free&wr_id=1&c_id=2\"oncontentvisibilityautostatechange=alert(1) style=content-visibility:auto type=hidden
Patch #
패치는 따옴표, CSS나 이벤트 핸들러 속성에 대한 검증을 추가하는 방식으로 진행되었다[3].
From 002e43e5fb84b465357b445772c881e196e100d3 Mon Sep 17 00:00:00 2001
From: thisgun <thisgun@naver.com>
Date: Thu, 28 Aug 2025 13:35:14 +0900
Subject: [PATCH] =?UTF-8?q?XSS=20=EC=B7=A8=EC=95=BD=EC=A0=90=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
bbs/view_comment.php | 2 +-
lib/common.lib.php | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/bbs/view_comment.php b/bbs/view_comment.php
index f7cb5d0872..8c83090d9d 100644
--- a/bbs/view_comment.php
+++ b/bbs/view_comment.php
@@ -7,7 +7,7 @@
$captcha_html = captcha_html('_comment');
}
-$c_id = isset($_GET['c_id']) ? clean_xss_tags($_GET['c_id'], 1, 1) : '';
+$c_id = isset($_GET['c_id']) ? preg_replace('/[\'",]/', '', clean_xss_tags($_GET['c_id'], 1, 1)) : '';
$c_wr_content = '';
@include_once($board_skin_path.'/view_comment.head.skin.php');
diff --git a/lib/common.lib.php b/lib/common.lib.php
index a7ab4197c0..ddb8bbace0 100644
--- a/lib/common.lib.php
+++ b/lib/common.lib.php
@@ -3429,6 +3429,12 @@ function clean_xss_tags($str, $check_entities=0, $is_remove_tags=0, $cur_str_len
$result = preg_replace('#([^\p{L}]|^)(?:javascript|jar|applescript|vbscript|vbs|wscript|jscript|behavior|mocha|livescript|view-source)\s*:(?:.*?([/\\\;()\'">]|$))#ius',
'$1$2', $result);
+ // 이벤트 핸들러 속성 제거 (예: onclick=, onerror= 등)
+ $result = preg_replace('/on\w+\s*=\s*(".*?"|\'.*?\'|[^\s>]+)/i', '', $result);
+
+ // 속성 제거 (CSS 기반 인젝션 차단)
+ $result = preg_replace('/\s*style\s*=\s*(".*?"|\'.*?\'|[^\s>]+)/i', '', $result);
+
if((string)$result === (string)$str) break;
$str = $result;
References #
- "CVE-2025-60859 Detail." nvd.nist.gov, Accessed: Mar. 30, 2026. [Online]. Available: https://nvd.nist.gov/vuln/detail/CVE-2025-60859
- creeperkirby, "Gnboard5 5.6.15 reflected XSS." creeperkirby.notion.site, Accessed: Mar. 30, 2026. [Online]. Available: https://creeperkirby.notion.site/Gnboard5-5-6-15-reflected-XSS-25c4fe7db8cf80efa20fc2ebefcfe61e
- thisgun, "XSS 취약점 수정." github.com, Accessed: Mar. 30, 2026. [Online]. Available: https://github.com/gnuboard/gnuboard5/commit/002e43e5fb84b465357b445772c881e196e100d3
- Masato Kinugawa [@kinugawamasato], "ooh, this works on Chrome Canary :D". X/Twitter. https://x.com/kinugawamasato/status/1816234368714871185. (Accessed: Mar. 30, 2026)
- kagla, "gnuboard5", (Version 5.6.15) [Source Code]. https://github.com/gnuboard/gnuboard5
last updated: