security: KVE-2026-2329 XHTML 등 실행형 첨부를 저장 전에 차단
게시판·1:1문의·폼메일·쇼핑몰 로고의 PHP 업로드 검사에서 위험 확장자를 거부한다. 대소문자와 다중 확장자 등 파일명 변형을 검사하고 클라이언트 검사도 일치시킨다. 검증: 위험 파일 및 정상 이미지·문서 파일명 격리 검증, 저장 전 차단 검증, PHP·JavaScript 문법 검사 통과.
This commit is contained in:
@@ -19,8 +19,8 @@ $logo_img_fields = array('logo_img', 'logo_img2', 'mobile_logo_img', 'mobile_log
|
|||||||
foreach ($logo_img_fields as $logo_img_field) {
|
foreach ($logo_img_fields as $logo_img_field) {
|
||||||
if (isset($_FILES[$logo_img_field]['name']) && $_FILES[$logo_img_field]['name']) {
|
if (isset($_FILES[$logo_img_field]['name']) && $_FILES[$logo_img_field]['name']) {
|
||||||
$filename = get_safe_filename($_FILES[$logo_img_field]['name']);
|
$filename = get_safe_filename($_FILES[$logo_img_field]['name']);
|
||||||
if (is_disallowed_svg_filename($filename)) {
|
if (is_disallowed_active_filename($filename)) {
|
||||||
alert('허용되지 않는 파일 확장자입니다. (svg, svgz)');
|
alert('허용되지 않는 파일 확장자입니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ for ($i=1; $i<=$attach; $i++) {
|
|||||||
$file_key = 'file'.$i;
|
$file_key = 'file'.$i;
|
||||||
if (isset($_FILES[$file_key]['name']) && $_FILES[$file_key]['name']) {
|
if (isset($_FILES[$file_key]['name']) && $_FILES[$file_key]['name']) {
|
||||||
$filename = get_safe_filename($_FILES[$file_key]['name']);
|
$filename = get_safe_filename($_FILES[$file_key]['name']);
|
||||||
if (is_disallowed_svg_filename($filename)) {
|
if (is_disallowed_active_filename($filename)) {
|
||||||
alert_close('허용되지 않는 파일 확장자입니다. (svg, svgz)');
|
alert_close('허용되지 않는 파일 확장자입니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,8 +136,8 @@ if($w == 'u' || $w == 'a' || $w == 'r') {
|
|||||||
if (isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
|
if (isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
|
||||||
foreach ($_FILES['bf_file']['name'] as $filename) {
|
foreach ($_FILES['bf_file']['name'] as $filename) {
|
||||||
$filename = get_safe_filename($filename);
|
$filename = get_safe_filename($filename);
|
||||||
if (is_disallowed_svg_filename($filename)) {
|
if (is_disallowed_active_filename($filename)) {
|
||||||
alert('허용되지 않는 파일 확장자입니다. (svg, svgz)');
|
alert('허용되지 않는 파일 확장자입니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ for ($i=1; $i<=10; $i++) {
|
|||||||
if (isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
|
if (isset($_FILES['bf_file']['name']) && is_array($_FILES['bf_file']['name'])) {
|
||||||
foreach ($_FILES['bf_file']['name'] as $filename) {
|
foreach ($_FILES['bf_file']['name'] as $filename) {
|
||||||
$filename = get_safe_filename($filename);
|
$filename = get_safe_filename($filename);
|
||||||
if (is_disallowed_svg_filename($filename)) {
|
if (is_disallowed_active_filename($filename)) {
|
||||||
alert('허용되지 않는 파일 확장자입니다. (svg, svgz)');
|
alert('허용되지 않는 파일 확장자입니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -70,6 +70,15 @@ function is_disallowed_svg_filename(filename)
|
|||||||
return /\.(svg|svgz)$/i.test(filename);
|
return /\.(svg|svgz)$/i.test(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_disallowed_active_filename(filename)
|
||||||
|
{
|
||||||
|
filename = filename || "";
|
||||||
|
if (/[\x00-\x1f\x7f]/.test(filename)) return true;
|
||||||
|
filename = filename.replace(/["'<>=#&!%\\()*+?]/g, "");
|
||||||
|
filename = filename.substring(filename.lastIndexOf("/") + 1).replace(/[ .]+$/, "");
|
||||||
|
return /\.(svgz?|xhtml|xht|xml|xsl|xslt|mht|mhtml|htc)([. :]|$)/i.test(filename);
|
||||||
|
}
|
||||||
|
|
||||||
function is_svg_upload_target(input)
|
function is_svg_upload_target(input)
|
||||||
{
|
{
|
||||||
var name = input.name || "";
|
var name = input.name || "";
|
||||||
@@ -92,7 +101,7 @@ function has_disallowed_svg_file(input)
|
|||||||
|
|
||||||
if (input.files && input.files.length) {
|
if (input.files && input.files.length) {
|
||||||
for (i=0; i<input.files.length; i++) {
|
for (i=0; i<input.files.length; i++) {
|
||||||
if (is_disallowed_svg_filename(input.files[i].name)) {
|
if (is_disallowed_active_filename(input.files[i].name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +109,7 @@ function has_disallowed_svg_file(input)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_disallowed_svg_filename(input.value);
|
return is_disallowed_active_filename(input.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_disallowed_svg_upload(form)
|
function check_disallowed_svg_upload(form)
|
||||||
@@ -118,7 +127,7 @@ function check_disallowed_svg_upload(form)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert("허용되지 않는 파일 확장자입니다. (svg, svgz)");
|
alert("허용되지 않는 파일 확장자입니다.");
|
||||||
$(form).find("input:submit, button:submit, input:image").prop("disabled", false);
|
$(form).find("input:submit, button:submit, input:image").prop("disabled", false);
|
||||||
invalid_file.focus();
|
invalid_file.focus();
|
||||||
|
|
||||||
@@ -799,7 +808,7 @@ $(function() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert("허용되지 않는 파일 확장자입니다. (svg, svgz)");
|
alert("허용되지 않는 파일 확장자입니다.");
|
||||||
this.value = "";
|
this.value = "";
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+12
-1
@@ -4236,7 +4236,18 @@ function get_safe_filename($name)
|
|||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 업로드 파일명이 SVG 또는 SVGZ 확장자인지 확인
|
// 브라우저에서 실행될 수 있는 첨부 확장자를 저장 전에 거부한다.
|
||||||
|
function is_disallowed_active_filename($filename)
|
||||||
|
{
|
||||||
|
if (!is_string($filename)) return true;
|
||||||
|
if (preg_match('/[\x00-\x1f\x7f]/', $filename)) return true;
|
||||||
|
$filename = basename(str_replace('\\', '/', $filename));
|
||||||
|
$filename = rtrim($filename, ' .');
|
||||||
|
// 다중 확장자 및 Windows 대체 데이터 스트림 표기도 차단한다.
|
||||||
|
return (bool) preg_match('/\.(?:svgz?|xhtml|xht|xml|xsl|xslt|mht|mhtml|htc)(?:[. :]|$)/i', $filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기존 스킨 및 플러그인과의 호환을 위한 SVG 검사 함수
|
||||||
function is_disallowed_svg_filename($filename)
|
function is_disallowed_svg_filename($filename)
|
||||||
{
|
{
|
||||||
if (!is_string($filename) || $filename === '') {
|
if (!is_string($filename) || $filename === '') {
|
||||||
|
|||||||
Reference in New Issue
Block a user