baserCMS クラスリファレンス

BcThemeFileService
in package
implements BcThemeFileServiceInterface

BcThemeFileService

Table of Contents

Interfaces

BcThemeFileServiceInterface
BcThemeFileServiceInterface

Methods

getBaseDir()  : string
テーマ/プラグインの当該テンプレートタイプのベースディレクトリを取得する
getFullpath()  : string
fullpathを作成
assertWithinPluginsDir()  : void
読み出し対象のパスがプラグイン配置ルート(App::path('plugins'))配下に収まっているか検証する
assertWithinSourceDir()  : void
コピー元のパスが、コピー元テーマ/プラグインの当該タイプのディレクトリ配下に収まっているか検証する
assertWithinThemeDir()  : void
指定したパスがテーマディレクトリ配下に収まっているか検証する
isWithinThemeDir()  : bool
パスがテーマディレクトリ配下かどうか
normalizePath()  : string
パスを正規化する(../ を解決する)

Methods

getBaseDir()

テーマ/プラグインの当該テンプレートタイプのベースディレクトリを取得する

public getBaseDir(string $theme, string $plugin, string $type) : string

Admin web 経路(ThemeFilesController::parseArgs)が fullpath を組み立てる規則と同じ。 type が etc の場合はテンプレートディレクトリ直下(type ディレクトリを挟まない)。

Parameters
$theme : string

テーマ名(コピー元の場合はプラグイン名のこともある)

$plugin : string

プラグイン名(空の場合はテーマ自身)

$type : string

テンプレートタイプ

Tags
checked
noTodo
unitTest
Return values
string —

末尾に DS を含むベースディレクトリ

getFullpath()

fullpathを作成

public getFullpath(string $theme, string $plugin, string $type, string $path) : string
Parameters
$theme : string
$plugin : string
$type : string
$path : string
Tags
checked
noTodo
unitTest
Return values
string

assertWithinPluginsDir()

読み出し対象のパスがプラグイン配置ルート(App::path('plugins'))配下に収まっているか検証する

protected assertWithinPluginsDir(string $path) : void

パストラバーサル対策(GHSA-rqr8-gmx5-xvrr): 読み出し処理(ThemeFilesService::get() / ThemeFoldersService::get())でも境界を検証し、 config/ などテーマ・プラグイン外のファイルを読み出せないようにする。 管理画面ではテーマに加えてプラグイン自体のテンプレートも参照するため、 書き込み用の assertWithinThemeDir() より広いプラグイン配置ルートを境界とする。 配下でなければ BcException を投げる。

Parameters
$path : string

検証対象のパス(ファイル or ディレクトリ)

Tags
throws
BcException
checked
noTodo

assertWithinSourceDir()

コピー元のパスが、コピー元テーマ/プラグインの当該タイプのディレクトリ配下に収まっているか検証する

protected assertWithinSourceDir(array<string|int, mixed> $params) : void

copyToTheme() のコピー元 $params['fullpath'] は Admin web 経路では parseArgs() が URL から .. を除去せずに組み立てるため、任意のファイル/ディレクトリをカレントテーマの webroot 配下へコピーして公開 URL から取得できてしまう。コピー元も境界を検証する。

Parameters
$params : array<string|int, mixed>

theme / plugin / type / fullpath を含む配列

Tags
throws
BcException
checked
noTodo
unitTest

assertWithinThemeDir()

指定したパスがテーマディレクトリ配下に収まっているか検証する

protected assertWithinThemeDir(string $path[, string|null $theme = null ]) : void

パストラバーサル対策(GHSA-2pj4-v76f-wjvx)の最終防衛線。 Admin web 経路の create()/update() はリクエストの fullpath を直接書き込み先に使い getFullpath() の境界チェックを通らないため、実際の書き込み sink でも テーマディレクトリ配下であることを必ず検証する。配下でなければ BcException を投げる。

許可する境界は次のとおり。

  • $theme を指定した場合: そのテーマのディレクトリ配下のみ
  • 未指定の場合: インストール済みの全テーマ(Theme / AdminTheme)のディレクトリ配下

以前は App::path('plugins') 配下(plugins/ と vendor/baserproject/ 全体)を許可していたため、 fullpath に .. を含めることで編集中のテーマ以外(コアプラグイン等)へ書き込めた。 テーマ以外のプラグインディレクトリは書き込み先として許可しない。

書き込み処理(ThemeFileForm::_execute / copy)は rawurldecode() を 1 回かけた値を使うため、 生の値に加えて 1 回デコードした値も検査する(GHSA-q7g3-qwrc-mp89)

Parameters
$path : string

検証対象のパス(ファイル or ディレクトリ)

$theme : string|null = null

書き込み先として許可するテーマ名(省略時は全テーマ)

Tags
throws
BcException
checked
noTodo
unitTest

isWithinThemeDir()

パスがテーマディレクトリ配下かどうか

private isWithinThemeDir(string $path[, string|null $theme = null ]) : bool
Parameters
$path : string
$theme : string|null = null

許可するテーマ名(省略時は全テーマ)

Return values
bool

normalizePath()

パスを正規化する(../ を解決する)

private normalizePath(string $path) : string
Parameters
$path : string
Return values
string
On this page

Search results