Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion data/class/helper/SC_Helper_FileManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,8 @@ public static function convertToAbsolutePath($path)
}

// USER_REALDIR 以下のパスかどうか
if ($path === false || !str_contains($path, realpath(USER_REALDIR))) {
$userRealDir = realpath(USER_REALDIR);
if ($path === false || $userRealDir === false || !str_starts_with($path.'/', $userRealDir.'/')) {
$path = realpath(USER_REALDIR);
}

Expand Down
14 changes: 9 additions & 5 deletions data/class/pages/admin/design/LC_Page_Admin_Design_CSS.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function action()
switch ($this->getMode()) {
// データ更新処理
case 'confirm':
if (!$is_error) {
if (!$is_error && $this->checkPath($this->css_name)) {
$this->arrErr = array_merge($this->arrErr, $this->lfCheckError($objFormParam, $this->arrErr));
if (SC_Utils_Ex::isBlank($this->arrErr)) {
if ($this->doRegister(
Expand All @@ -111,7 +111,7 @@ public function action()
}
break;
case 'delete':
if (!$is_error) {
if (!$is_error && $this->checkPath($this->css_name)) {
if ($this->doDelete($css_path)) {
$arrPram = [
'device_type_id' => $this->device_type_id,
Expand Down Expand Up @@ -289,16 +289,20 @@ public function getCSSDir($device_type_id)
}

/**
* 文字列に[./]表記がないかをチェックします
* パストラバーサルを防ぐためのパスチェック
*
* @param string $str
*
* @return bool
*/
public function checkPath($str)
{
// 含む場合はfalse
if (preg_match('|\./|', $str)) {
if (SC_Utils_Ex::isBlank($str)) {
return true;
}

// ディレクトリトラバーサルのブロック
if (str_contains($str, '..') || str_contains($str, './') || str_contains($str, '/')) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,13 @@ public function createPHPFile($filename)
{
$path = USER_REALDIR.$filename.'.php';

// パストラバーサル防止: realpath で正規化し USER_REALDIR 内であることを検証
$parentDir = realpath(dirname($path));
$userRealDir = realpath(USER_REALDIR);
if ($parentDir === false || $userRealDir === false || !str_starts_with($parentDir.'/', $userRealDir.'/')) {
return false;
}

if (file_exists($path)) {
return true;
}
Expand Down
25 changes: 22 additions & 3 deletions data/class/pages/admin/design/LC_Page_Admin_Design_UpDown.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,28 @@ public function lfCheckError(&$objFormParam, &$objUpFile)
if (!is_array($arrArchive)) {
$arrErr['template_file'] = '※ テンプレートファイルが解凍できません。許可されている形式は、tar/tar.gzです。<br />';
} else {
$make_temp_error = $objUpFile->makeTempFile('template_file', false);
if (!SC_Utils_Ex::isBlank($make_temp_error)) {
$arrErr['template_file'] = $make_temp_error;
// アーカイブ内容の安全性チェック
foreach ($arrArchive as $file) {
$entryName = $file['filename'];
if (str_contains($entryName, '..')) {
$arrErr['template_file'] = '※ アーカイブに不正なパスが含まれています。<br />';
break;
}
if (str_starts_with($entryName, '/')) {
$arrErr['template_file'] = '※ アーカイブに絶対パスが含まれています。<br />';
break;
}
if (isset($file['typeflag']) && $file['typeflag'] === '2') {
$arrErr['template_file'] = '※ シンボリックリンクは許可されていません。<br />';
break;
}
}

if (empty($arrErr['template_file'])) {
$make_temp_error = $objUpFile->makeTempFile('template_file', false);
if (!SC_Utils_Ex::isBlank($make_temp_error)) {
$arrErr['template_file'] = $make_temp_error;
}
}
}

Expand Down
Loading