a-blog cms PHP API Reference

Filter
in package

Table of Contents

Constants

MAX_SCRUB_DEPTH  = 10
再帰スクラブの深さ上限。

Properties

$arrayKeyExactMatchKeys  : array<string|int, mixed>
配列のキーを完全一致でマスクする対象のリスト(scrubLogArray() 専用)。
$headerSensitiveFields  : array<string|int, mixed>
HTTPヘッダ専用の機密フィールドのリスト(部分一致でマスクする)。
$mask  : string
マスク文字列
$sensitiveFields  : array<string|int, mixed>
機密フィールドのリスト(部分一致でマスクする)
$urlQueryExactMatchKeys  : array<string|int, mixed>
URL のクエリ文字列を完全一致でマスクする対象のリスト(scrubUrl() 専用)。
$urlValueKeys  : array<string|int, mixed>
scrubLogArray() で値を丸ごとマスクせず scrubUrl() に通す対象のキー(大文字小文字を区別しない)。

Methods

__construct()  : mixed
コンストラクタ
getSafeArray()  : array<string|int, mixed>
安全にフィルタリングされた配列を取得
getSafeHeaders()  : array<string|int, mixed>
HTTPヘッダを安全にフィルタリングされた配列として取得する。
getSensitiveFields()  : array<string|int, mixed>
設定されている機密フィールド一覧を取得
registerSensitiveKeys()  : self
マスク対象のキーを登録する(拡張アプリ・ユーザー拡張向けの公開 API)。
scrubLogArray()  : array<string|int, mixed>
既存レコードの読み出し・ログ出力向けに配列を再帰的にスクラブする。
scrubUrl()  : string
URL のクエリ文字列から機密なトークン・認可コード等をスクラブし、パス上の メディアダウンロードハッシュ(無期限capability)もマスクする。
setMask()  : self
マスク文字列を設定
setSensitiveFields()  : self
機密フィールドを一括設定
unregisterSensitiveKeys()  : self
registerSensitiveKeys() で登録したキーを取り消す。
filterArray()  : array<string|int, mixed>
配列を再帰的にフィルタリング
getMaskedValue()  : string
マスクされた値を取得
getSensitiveKeyList()  : array<int, string>|null
target に対応する現在のリストを返す。未知の target なら null。
isExactMatchKey()  : bool
キーが配列キー用の完全一致マスク対象か判定する
isSensitiveField()  : bool
フィールド名が機密情報に該当するかチェック(部分一致)
isUrlValueKey()  : bool
キーがURL値を持つキーか判定する
normalizeSensitiveKeys()  : array<int, string>
登録・取り消しで受け取ったキーを文字列のリストへ正規化する。
scrubMediaDownloadHash()  : string
media-download/{mid}/{hash}/ のパスに含まれるハッシュ部分をマスクする。
setSensitiveKeyList()  : void
target に対応するリストを差し替える。未知の target は何もしない。

Constants

MAX_SCRUB_DEPTH

再帰スクラブの深さ上限。

private int MAX_SCRUB_DEPTH = 10

Why not: filterArray() / scrubLogArray() は自身を再帰呼び出しするため、循環参照配列 ($a['self'] = &$a; 等、拡張・プラグインからの入力を含む)を渡されると際限なく再帰し スタックオーバーフローで fatal になる。ScrubProcessor 経由で全ログレコードの context/extra が対象になった($_POST 限定ではなくなった)ため、露出面を塞ぐ意味で上限を設ける。

Properties

$arrayKeyExactMatchKeys

配列のキーを完全一致でマスクする対象のリスト(scrubLogArray() 専用)。

private array<string|int, mixed> $arrayKeyExactMatchKeys = ['acms-preview-mode', 'salt', 'context', 'preview-token', 'token', 'oauth_token', 'oauth_verifier']

Why not: urlQueryExactMatchKeys とは意図的に語彙を変えている。'code' / 'key' / 'state' は URL クエリキーとしては機密(認可コード・derived key・CSRF state)だが、配列キーとしては 汎用的な識別子名として実際に使われている(user_code の警告ログ・SQLSTATE・エイリアス/ カテゴリーコード・一括変更フィールドキー・RestoreStatus の処理状態等)。同じ語をここに 含めると、それらの調査に必要な情報がまるごと 'MASKED' に潰れてしまう ($_POST 用の sensitiveFields に 'cookie' を混ぜてはいけない理由と同型の問題)。

$headerSensitiveFields

HTTPヘッダ専用の機密フィールドのリスト(部分一致でマスクする)。

private array<string|int, mixed> $headerSensitiveFields = ['cookie', 'authorization', 'proxy-authorization', 'x-api-key']

Why not: cookie / authorization / proxy-authorization / x-api-key はハイフン区切りの HTTPヘッダ名(Cookie, Authorization, Proxy-Authorization, X-Api-Key)に一致させるための 表記で、$_POST 用の api_key(アンダースコア区切り)とは別に持つ必要がある。sensitiveFields 本体に混ぜると $_POST(cookie_policy_agree 等のフォーム項目)にまで cookie 等の 部分一致が及んでしまうため、getSafeHeaders() 専用の別リストとして分離している。

$mask

マスク文字列

private string $mask = '***MASKED***'

$sensitiveFields

機密フィールドのリスト(部分一致でマスクする)

private array<string|int, mixed> $sensitiveFields = ['password', 'passwd', 'pass']

$urlQueryExactMatchKeys

URL のクエリ文字列を完全一致でマスクする対象のリスト(scrubUrl() 専用)。

private array<string|int, mixed> $urlQueryExactMatchKeys = ['acms-preview-mode', 'key', 'salt', 'context', 'preview-token', 'token', 'code', 'state', 'oauth_token', 'oauth_verifier']

Why not: 部分一致にすると key が field_key 等の識別子カラム名まで巻き込んで全滅させるため (既存の sensitiveFields に 'key' を追加しない理由と同じ)、完全一致専用のリストとして 分離している。

Why not: 'code' と 'state' は配列キー用の arrayKeyExactMatchKeys には含めない (下記コメント参照)が、SNS ログインコールバックの ?code=…&state=…(OAuth 認可コード・ CSRF 対策の state パラメータ)をスクラブするにはクエリキーとして必要なため、こちらには残す。

Why not: 隣の $sensitiveFields / $mask は型付きプロパティ(PHP 7.4+)だが、この新規プロパティ 以降は意図的に型宣言を付けていない。このクラスは 301x(PHP 7.3 以上サポート)へ手動で バックポートされるため、新規追加分は型付きプロパティに依存しない書き方に揃えている。

$urlValueKeys

scrubLogArray() で値を丸ごとマスクせず scrubUrl() に通す対象のキー(大文字小文字を区別しない)。

private array<string|int, mixed> $urlValueKeys = ['url', 'referrer', 'referer']

Methods

__construct()

コンストラクタ

public __construct([array<string|int, mixed> $additionalFields = [] ][, string $mask = '***MASKED***' ]) : mixed
Parameters
$additionalFields : array<string|int, mixed> = []
$mask : string = '***MASKED***'

getSafeArray()

安全にフィルタリングされた配列を取得

public getSafeArray(array<string|int, mixed> $data) : array<string|int, mixed>
Parameters
$data : array<string|int, mixed>
Return values
array<string|int, mixed>

getSafeHeaders()

HTTPヘッダを安全にフィルタリングされた配列として取得する。

public getSafeHeaders(array<string|int, mixed> $headers) : array<string|int, mixed>

getSafeArray() の機密フィールドリストに headerSensitiveFields を加えた上でマスクする。

Parameters
$headers : array<string|int, mixed>
Return values
array<string|int, mixed>

getSensitiveFields()

設定されている機密フィールド一覧を取得

public getSensitiveFields() : array<string|int, mixed>
Return values
array<string|int, mixed>

registerSensitiveKeys()

マスク対象のキーを登録する(拡張アプリ・ユーザー拡張向けの公開 API)。

public registerSensitiveKeys("field"|"header"|"urlQuery"|"arrayKey" $target, array<int, string>|string $keys) : self

既存の値を保ったまま足すため、コア側の既定リストを壊さずにプラグイン固有の 機密キーを登録できる。この Filter はコンテナに acms-logger-filter として singleton 登録され、ScrubProcessor と各ハンドラが同一インスタンスを参照するので、後から登録しても 以降のログすべて(監査ログ・アラートメール・エラーログ)に効く。

プラグインからは ServiceProvider::init() で次のように呼ぶ:

use Acms\Services\Facades\Application as App;

App::make('acms-logger-filter')
    ->registerSensitiveKeys('field', ['myplugin_client_secret']);

Why not: Hook(extendsLogFilter 等)の拡張ポイントは設けない。プラグインの Hook は app テーブルを引いたあと main.php で attach されるため、LoggerServiceProvider の 登録時点では collection に入っておらず発火しても呼ばれない。プラグインの init() から この公開メソッドを直接呼べば順序の問題が起きないので、フック機構を増やす必要がない。

Why not: setSensitiveFields() を拡張側に案内しない。あちらは配列をまるごと差し替えるため、 プラグインが呼ぶとコアの既定リスト(password 等)が消えて他の機密値が平文で残る。

Parameters
$target : "field"|"header"|"urlQuery"|"arrayKey"

登録先のリスト

  • field : $_POST・context・extra のキーに部分一致(例: myplugin_secret)
  • header : HTTP ヘッダ名に部分一致(ハイフン区切りで指定する。例: x-myplugin-token)
  • urlQuery : URL のクエリキーに完全一致(部分一致にすると識別子カラム名を巻き込むため)
  • arrayKey : 配列キーに完全一致
$keys : array<int, string>|string

登録するキー(1件なら文字列でも可)

Return values
self

scrubLogArray()

既存レコードの読み出し・ログ出力向けに配列を再帰的にスクラブする。

public scrubLogArray(array<string|int, mixed> $data[, int $depth = 0 ]) : array<string|int, mixed>

部分一致マスク(sensitiveFields)・完全一致マスク(arrayKeyExactMatchKeys)・URL値を持つ キー(urlValueKeys)への scrubUrl() 適用のすべてを、ネストした配列にも再帰的に適用する。 AcmsLogger::warning('...', ['request' => $someArray]) のように1段包んだ context を渡す 拡張・プラグインがあるため、トップレベル限定では nested な salt/context/token 等が 素通りしてしまう。

Why not: urlValueKeys の値には scrubUrl($value, false) を使う。WebProcessor が注入する extra.url / extra.referrer は htmlspecialchars 前の生の値であり、scrubUrl() の既定(再度 htmlspecialchars する)を適用すると生の表現に '&' 等の HTML エンティティが literal 混入してしまうため。

Parameters
$data : array<string|int, mixed>
$depth : int = 0
Return values
array<string|int, mixed>

scrubUrl()

URL のクエリ文字列から機密なトークン・認可コード等をスクラブし、パス上の メディアダウンロードハッシュ(無期限capability)もマスクする。

public scrubUrl(string|null $url[, bool $reEscape = true ]) : string

REQUEST_URL / REFERER は htmlspecialchars(ENT_QUOTES) 済みで '&' が '&' に なっているため、クエリ区切りの検出前に htmlspecialchars_decode() で戻す (Services/Preview/Engine.php の shareUrlFormat() と同じ手当て)。処理後は再度 htmlspecialchars(ENT_QUOTES) して元の表現に戻す。これを怠ると (1) DB に生の '<' '"' '&' が 保存され将来テンプレート等に生出力した時点で stored XSS になり得る、(2) 書き込み時・ 読み出し時の両方で scrubUrl() を通すため二重デコードでクエリ値中の '&' がパラメータ区切りに 化ける、という2つの問題が起きる。

機密クエリは値だけを mask に置き換え、キー自体は残す(削除しない)。削除すると 「認証URLでアクセスされた」という監査上重要な事実そのものが消えてしまうため。

Parameters
$url : string|null
$reEscape : bool = true

処理後に htmlspecialchars(ENT_QUOTES) で再エスケープするか。 REQUEST_URL / REFERER のようにすでにエスケープ済みの値を渡す場合は true(既定)。 WebProcessor が注入する extra.url / extra.referrer のようにエスケープ前の生の値を渡す場合は false にする(true のままだと生の表現に '&' 等が混入し、監査ログ詳細やプレーンテキストの エラーログファイルに HTML エンティティが literal 表示されるノイズになる)。

Return values
string

setMask()

マスク文字列を設定

public setMask(string $mask) : self
Parameters
$mask : string
Return values
self

setSensitiveFields()

機密フィールドを一括設定

public setSensitiveFields(array<string|int, mixed> $fields) : self
Parameters
$fields : array<string|int, mixed>
Return values
self

unregisterSensitiveKeys()

registerSensitiveKeys() で登録したキーを取り消す。

public unregisterSensitiveKeys("field"|"header"|"urlQuery"|"arrayKey" $target, array<int, string>|string $keys) : self

自分が登録したキーを撤回するための API。コアの既定リストにあるキーも指定すれば外せるが、 外すと本来隠れていた値が平文でログに残るため、自分で登録したキー以外は渡さないこと。

Parameters
$target : "field"|"header"|"urlQuery"|"arrayKey"

取り消し先のリスト(registerSensitiveKeys() 参照)

$keys : array<int, string>|string

取り消すキー(1件なら文字列でも可)

Return values
self

filterArray()

配列を再帰的にフィルタリング

protected filterArray(array<string|int, mixed> $data, array<string|int, mixed> $sensitiveFields[, int $depth = 0 ]) : array<string|int, mixed>
Parameters
$data : array<string|int, mixed>
$sensitiveFields : array<string|int, mixed>
$depth : int = 0
Return values
array<string|int, mixed>

getMaskedValue()

マスクされた値を取得

private getMaskedValue() : string
Return values
string

getSensitiveKeyList()

target に対応する現在のリストを返す。未知の target なら null。

private getSensitiveKeyList(string $target) : array<int, string>|null

Why not: プロパティを可変名($this->$name)で触らない。対象を列挙して static に解決する ことで、想定外の target 文字列で無関係なプロパティを読み書きされる余地をなくす。

Why not: 未知の target で例外を投げない。ログ出力の設定ミスで例外を投げると、 本来記録すべきログそのものを落とすことになるため、呼び出し側で黙って捨てる。

Parameters
$target : string
Return values
array<int, string>|null

isExactMatchKey()

キーが配列キー用の完全一致マスク対象か判定する

private isExactMatchKey(string $key) : bool
Parameters
$key : string
Return values
bool

isSensitiveField()

フィールド名が機密情報に該当するかチェック(部分一致)

private isSensitiveField(string|int $fieldName, array<string|int, mixed> $sensitiveFields) : bool
Parameters
$fieldName : string|int
$sensitiveFields : array<string|int, mixed>
Return values
bool

isUrlValueKey()

キーがURL値を持つキーか判定する

private isUrlValueKey(string $key) : bool
Parameters
$key : string
Return values
bool

normalizeSensitiveKeys()

登録・取り消しで受け取ったキーを文字列のリストへ正規化する。

private normalizeSensitiveKeys(array<int, string>|string $keys) : array<int, string>
Parameters
$keys : array<int, string>|string
Return values
array<int, string>

scrubMediaDownloadHash()

media-download/{mid}/{hash}/ のパスに含まれるハッシュ部分をマスクする。

private scrubMediaDownloadHash(string $url) : string

このハッシュは $mid と固定ソルトだけから決まる無期限capabilityで、クエリ文字列では ないため scrubUrl() のクエリ用パターンでは届かない。パス専用に別途処理する。

Parameters
$url : string
Return values
string

setSensitiveKeyList()

target に対応するリストを差し替える。未知の target は何もしない。

private setSensitiveKeyList(string $target, array<int, string> $keys) : void
Parameters
$target : string
$keys : array<int, string>

        
On this page

Search results