セキュリティ規則
サードパーティ製の資料が守るべきセキュリティ規則です。ここにある項目は、実際の事故のパターンから生まれたものです。
出力:XSS
- ユーザー入力を出力するときは、常に
{{ }}(エスケープ)を使ってください。 {!! !!}は、コアがサニタイズした HTML(エディター本文getContent())にだけ使ってください。サニタイズされていない値を入れた瞬間に XSS になります。- JS の文脈に値を入れるときは、
@json($value)または|escapejsフィルターを使ってください。文字列の連結でスクリプトを組み立てないでください。
入力:検証はサーバーで
- 画面(JS)での検証は便宜にすぎません。すべての検証を proc アクション(サーバー)でもう一度行ってください。
- 数値は
(int)でキャストし、許可リストがある値はin_array(..., true)で確認してください。 - クエリ XML のバインディングを使う限り SQL インジェクションは防がれますが、
filter="number"とnotnullでもう一段締めます。条件のない update/delete にならないよう、主要な条件には必ず notnull を付けてください。
CSRF とアクション設計
- データを変更する動作は、必ず proc アクション+POST で作ってください。コアが CSRF トークンを自動でチェックします。
- GET(disp)でデータを変更してはいけません。リンク1つで削除が実行される構造は、CSRF チェックも回避されてしまいます。
- 外部サーバーが呼び出すコールバックにだけ
standalone="true" check-csrf="false"を付け、そのアクションの中で独自の検証(署名・状態トークン・サーバー間の再確認)を行ってください。ブラウザーを経由してきた値は信頼しないでください。
権限の確認
- module.xml の
permission属性だけに頼らず、所有者の確認が必要な動作(自分の投稿の修正など)は、アクションの中でmember_srlを照合してください。 - 管理機能は
permission="manager"+画面での権限分岐の二重でかけてください。画面でボタンを隠すだけでは保護になりません。
ファイルのアップロード
- 拡張子は許可リスト方式でチェックしてください(禁止リストは回避されます)。
- サイズ制限を設け、保存ファイル名には元のファイル名を使わず新しく作ってください。
- 実行されうるファイル(.php など)がアップロード先で実行されないよう、コアのファイルモジュールのパス(
files/attach)を使ってください。Web サーバーの設定がこのパスでの PHP 実行を遮断します。
秘密情報の保管
- トークン・キーを DB に保存するときは、ハッシュ(照会用)または暗号化(復号が必要な場合)で保存してください。コアの
Zittme\Framework\Securityに暗号化ツールがあります。 - 一時的な状態ファイルを
files/cache以下に作る場合は、Web から直接アクセスできないか確認してください。Web サーバーの遮断ルールにない新しいパスであれば、ルールを追加する必要があります。実際に、このパスが HTTP 200 で露出した事故がありました。 - 認証情報をコードにハードコーディングしないでください。モジュール設定(insertModuleConfig)に保存し、画面ではマスキングして表示してください。
外部連携
- 自サーバーが受け取るコールバック:ブラウザー経由の値を信用せず、サーバー間通信で再検証してください(決済金額、認証結果など)。
- 認証コードの交換には、状態トークン(state)や PKCE のような標準的な保護を使ってください。
- レスポンスで不要な Set-Cookie が送られていないか確認してください。クロスサイトのコールバックでセッション Cookie が新たに発行されると、ユーザーの既存のセッションを上書きしてしまう可能性があります。
最終チェックリスト
- ユーザー入力がエスケープなしで出力される箇所はないか
- proc を使わず GET でデータが変更される箇所はないか
- 条件のない update/delete クエリはないか
- アップロードの拡張子・サイズのチェックがサーバー側にあるか
- 秘密情報が平文で保存されていたり、Web に露出するパスに置かれていたりしないか