Conversation
- mypage_* は会員でログインした front_login コンテキストで実行する (ユーザーを持たないコンテキストでは sequence-activeScan がセッションを引き継がない) - plugin_related_product / plugin_sales_report は管理画面だけを操作するため admin コンテキストにする - ユーザーと forced user はコンテキストから決める (-c で明示した場合も同じ) - admin コンテキストで before_script を省略した場合は admin_login.zst を使う - -p でスキャンポリシーを指定できるようにする (省略時は同梱の Sequence ポリシー) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Path Traversal (ルール 6) のうち、URL 末尾の文字列をファイル名として送るチェックは、 比較用の存在しないファイル名 (38 文字) が入力欄の文字数上限でバリデーションエラーになる だけで High を出す。このチェックは根拠 (evidence) を持たず、ファイルを読み取れた本来の 検知は根拠を持つため、根拠が空のものだけを判定から外す。レポートには残す。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 4.4 で変わったフォーム項目・パスワード要件・CSRF トークンの取得位置に追従する - 会員を作るシナリオはメールアドレスを乱数で一意にし、固定の会員・受注 ID を 作成時に取得した ID に置き換える (再生や能動スキャンでの重複登録を避ける) - 管理画面へログインしていなかった before_script にログインを追加する - admin_mail_edit / front_new_item は作成から削除までを一続きで組み直す - 購入フロー画面にヘッダー検索フォームが無いことに合わせて formIndex を直す Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sequence-activeScan は同梱の Sequence ポリシーを使い、CI のマウント先 (/zap/policies) は ZAP が読むディレクトリ (~/.ZAP/policies) ではなかったため、このファイルは読まれていなかった。 GUI 用の docker-compose.owaspzap.yml のマウントも外し、ZAP 同梱の既定ポリシーを使う。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- EC-CUBE を APP_ENV=prod / APP_DEBUG=0 で起動する。docker-compose.yml が dev を直書きしており、 ワークフローの環境変数では上書きされていなかった - バンドル版プラグインを各リポジトリの 4.4 ブランチから導入する (4.2 版は 4.4 で動かない) - ターゲットと個別の設定を zap/targets.json に移し、入力 targets (正規表現) で絞り込めるようにする - 入力 policy で Smoke (全ルール OFF、zst の再生だけを確認) を選べるようにする - 自動化プランは Zest の再生失敗があっても成功扱いになるため、ログから判定する。 Smoke では失敗、Sequence では能動スキャンによる状態変化で失敗し得るため警告に留める - before_script のログインをシナリオへ引き継ぐため connection.httpStateEnabled を有効にする - thread_per_host を scanner.threadPerHost として ZAP に渡す (これまでは使われていなかった) - before_script の既定値は generate_automation_config.sh に任せ、ワークフロー側の上書き・ パッチ・customer-id の置換をやめる - 別ランナーで動くため効果の無かった prune ジョブを削除し、scan に timeout-minutes を設定する Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
securitychecker-plugin は非公開リポジトリのため CI から匿名で clone できず、 プラグインの導入ステップが失敗していた。これを操作するシナリオは無いため導入しない。 あわせて、Autorun まで到達しなかった場合に Check results が誤って 「自動化プランが失敗」を出さないようにする。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 環境の準備 (プラグインの導入・レートリミッタの緩和・ZAP のアドオンと Smoke ポリシー・ データの定期削除)、プランの生成と実行、結果の判定を zap/bin/ に切り出し、CI からも呼ぶ - 導入するプラグインを zap/plugins.txt で管理する - zap/local/ にレーン単位で並列に実行するスクリプトを追加する。ターゲットごとに DB を 準備直後の状態へ戻してから実行し、zap/targets.json を共有のキューにして複数レーンで回す - 結果の判定は Smoke では再生の失敗も失敗、Sequence では警告に留める (従来の CI と同じ) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
仕組み (targets.json・ポリシー・プラグイン)、結果の判定、GitHub Actions とローカルでの 実行方法、既知の再生の失敗、シナリオを追加・修正するときの注意を記載する。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
owasp/zap2docker-stable は取得できなくなっているため、docker-compose.owaspzap.yml が ビルドできなかった。後継の公式イメージは webswing を同梱しており、日本語フォントを 追加する手順はそのまま使える。 起動時に ZAP のルート CA (秘密鍵を含む) を zap/ へ書き出す設定のため、.gitignore に追加する。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.4 で追加された FAQ 管理 (登録・編集・並び替え・削除) を再生するシナリオ。 お知らせ管理のシナリオと同じ流れで、登録後のリダイレクト先から FAQ の ID を取得する。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- admin_calendar: 定休日の登録・インライン編集 (mode=edit_inline, EC-CUBE#6675)・削除。 税率設定と同じ画面構成のため、admin_tax と同じ流れで一覧の先頭の編集フォームから ID を取得する - admin_category_faq: カテゴリ別 FAQ の登録と、0 件にして保存する削除。 FAQ 欄の描画を示す faqs_rendered を送らないと FAQ が無視されるため、必ず送る Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
条件を変えて同じターゲットを実行すると、zap/local/out/<policy>/<target>/ の結果が上書きされる。 比較のために複数の条件で並行して実行できるよう、出力先を環境変数で指定できるようにする。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- front_cookie_consent: Cookie 同意の設定ページ・ポリシー・同意状態の保存。 before_script (admin_enable_cookie_consent.zst) で店舗設定の Cookie 同意を ON にする - mypage_shopping_shipping: 購入手続き中に会員の登録済みお届け先を編集・削除する - mypage_refund_request: マイページから返品・返金を申請する。 before_script (admin_create_delivered_order.zst) で購入した受注を発送済みにする - admin_refund_request: 管理画面で返品・返金申請を検索し、対応開始・承認・CSV 出力を行う。 before_script (admin_create_refund_request.zst) で発送済みの受注に申請を作成する - front_block: FAQ・定休日カレンダー・新着商品のブロックを追加 README に、シナリオ作成時の注意 (正規表現での ID 抽出、formIndex のずれ、 response 要素による読み込み失敗、admin コンテキストでの再ログイン) を追記した。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ブロックの取得は GET で CSRF トークンを検証しないため、ヘッダー自体を送らない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
61 of 72 tasks
- zap/bin/coverage.sh: EC-CUBE のルートのうち、どのシナリオのリクエストも一致しないものを一覧にする。 対象外にするルート (インストーラ、ストアのプラグイン管理) は理由と一緒に zap/coverage_exclude.txt に書く - zap/bin/attack_counts.sh: シナリオのリクエストごとに、EC-CUBE が受けたリクエストの件数と応答の内訳を数える - autorun.sh: スキャン中のアクセスログを回収して attacks.tsv を出力し、Sequence ではパラメータがあるのに 正常な応答が数件しか無いリクエストを「攻撃が届いていない可能性」として通知する (判定には影響させない) 画面を通っていても攻撃が届いていない例として、entry のパスワード再設定は再設定用の URL が使用済みで 攻撃がすべて 404 になり、再設定フォームは実質スキャンされていないことが分かった。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- delete_data.sh: dtb_tag を 5 秒ごとに作成直後のものまで削除していたため、admin_product_tag が 作成したタグを編集する前に消され、Smoke でも再生に失敗することがあった。dtb_tag は作成日時を 持たないため、2 周前 (10 秒以上前) に既にあった ID までを削除する - prepare_zap.sh: zap.sh -cmd がプロキシのポートを確保できずに終了することがある (Address already in use)。原因は特定できていないため、3 回まで再実行する Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
doc4 の「テストが止まらないようにするための設定」を 4.4 向けに作り直し、目的ごとに zap/patches/*.patch に分けた (会員登録・パスワード再設定・お届け先・退会・会員情報・お気に入り・ 購入完了・管理画面の設定・規格の削除)。 スキャンする対象がリリースするコードと変わり、保存の時点で起きるエラーは検出できなくなるため、 既定のスキャンでは当てない。ローカルは zap/local/patch.sh、GitHub Actions は workflow_dispatch の patches で選んだときだけ当てる。当て済みかを先に判定し、二重に当てて .rej を残さないようにしている。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
generate_automation_config.sh は zap/automation/<target>.yml に書き、autorun.sh は読み終えると 削除していたため、別のレーンで同じターゲットを同時に実行すると、一方が削除したファイルを もう一方が読んで空のプランになった。生成先を -o で指定できるようにし、autorun.sh は出力先の ディレクトリへ生成させる。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 4.4 #7196 +/- ##
==========================================
- Coverage 78.47% 78.43% -0.05%
==========================================
Files 651 651
Lines 31391 31384 -7
==========================================
- Hits 24635 24615 -20
- Misses 6756 6769 +13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
作成から 6 秒で削除していたため、Smoke でも作成から削除の手順まで 8 秒ほどかかる admin_payment が、掃除のループの位相次第で 404 に なっていた (CI の全ターゲット Smoke で発生)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
パッチの有無で attacks.tsv の正常な応答を比べ、改善したのは mypage-delivery-keep だけだったため、残りの 8 本を削除する。 - 削除を無効にするもの: 削除のリクエストは _token と _method だけで、 _method への攻撃は Symfony が 400 を返すため、削除済みかに関わらず届かない - カートを残すもの: /shopping/checkout は CSRF トークンだけで攻撃されない - 会員を保存しないもの: entry の後半の再生が壊れる - 再設定のキーを残すもの: 再設定フォームは攻撃前の再生で既に 404 README に評価結果と、multipart のリクエストに攻撃が送られないことを記載する。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ghcr.io/ec-cube/zaproxy:0.1.2 も中身は公式の ZAP 2.17.0 だが、作り方が 公開されておらず再現できず、ZAP の更新にも追従しない。GUI 用の zap/Dockerfile と同じ公式のイメージにそろえる。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EC-CUBE/coupon-plugin#199 で修正され、plugin_coupon_guest_shopping も Smoke・Sequence ともに再生に成功するようになった。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ZAP は Content-Type を小文字にしてから boundary を取り出すため、 ブラウザが付ける大文字を含む boundary (----WebKitFormBoundary...) では 本文を分割できず、各スキャンルールが IndexOutOfBoundsException で中断して 攻撃が 1 件も送られていなかった (商品・支払方法の登録、CSV・テンプレート・画像のアップロード)。 - zst の boundary を小文字にし、boundary の行の前の改行を CRLF に揃える - 再発を防ぐため zap/bin/lint_zst.sh を追加し、CI の Prepare matrix で実行する multipart のリクエスト 14 件で、EC-CUBE が受けたリクエストが 1〜3 件から 425〜4123 件に増えた。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ルール 40026 (Cross Site Scripting (DOM Based)) は、ブラウザで URL の # 以降とクエリ文字列に 値を入れて alert() の実行を見るもので、POST の本文やシナリオのステップの状態は扱わない。 EC-CUBE の JavaScript は location.hash / location.search を読んでおらず、全ターゲットのスキャンで 1 件も検出していない。一方で 1 ステップが ZAP の待ち時間の上限 (600 秒) に達することがあり、 上限後もスレッドが止まらず次のルールの所要時間まで延ばしていた。 - prepare_zap.sh で、同梱の Sequence ポリシーから 40026 だけを OFF にした EC-CUBE ポリシーを作る (同梱のポリシーは読み取り専用のため別ファイル。<locked> を外すと同梱に無いルールまで有効になるため残す) - autorun.sh は Sequence の指定で EC-CUBE ポリシーを使う - 除外の理由を zap/README.md に記載する plugin_mailmagazine_send は 3 時間 3 分から 18 分、admin_payment は 11 分から 2 分 20 秒になった。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- delete_files.sh が商品画像の一時ファイルを十数秒で消していたため、画像のアップロードを 能動スキャンしている間に一時ファイルが消え、次の商品登録の再生が入力エラーで失敗していた。 html/upload/temp_image だけ 60 分残す - 商品登録・編集の POST に、ブラウザが送る admin_product[faqs_rendered] を足す。 無いと入力エラーの画面の再表示が 500 になり (EC-CUBE#7192)、攻撃の応答が入力エラーの画面まで届かない admin_product_edit は再生の失敗が 6/11 から 0/11 になり、商品編集への攻撃 2471 件が 404 だけだったものが登録の処理まで届くようになった。商品登録への攻撃の 500 は 676/2079 件から 0 件になった。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ZAP は再生の成否を状態コードで判定するため、入力エラーの画面が 200 で返ると成功とみなす。
その場合、確認画面などの後続の画面には能動スキャンの攻撃が届かない。
- Smoke では、再生で入力エラーの画面が返った POST を Form error: としてログに出し、
check_results.sh で再生の失敗として数える (scripts/report_form_errors.js)。
再生と攻撃は ZAP の中で区別できないため、攻撃を送らない Smoke に限る
- 全ターゲットの Smoke で見つかったシナリオを直す
- entry: 確認画面への POST に、MailMagazine44 が足す必須項目 entry[mailmaga_flg] が無かった。
確認画面が一度も表示されず、仕込んだ反射型 XSS を検知できなかった原因 (EC-CUBE#7190)。
直してから仕込みを再現し、ルール 40012 で検知されることを確認した
- admin_order_edit_search: お届け日は single_text になったため、年・月・日に分けず 1 項目で送る
- plugin_mailmagazine_send: 記録した環境にしか無いテンプレート ID を送っていた。シナリオの中で
テンプレートを作り、ID を応答から取り出して、ブラウザと同じく /select/{id} へ送る。
記録したときの CSRF トークンが値のまま残っていたものも変数にする
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 2, 2026
CI は EC-CUBE#6890 で mailpit に移行済みだが、開発環境の docker-compose.yml と agentic-commerce-e2e.yml には Docker Hub の schickling/mailcatcher が残っていた。 - docker-compose.yml: mailpit を ghcr.io から取得する (バージョンは .github/actions/mailpit と揃えて v1.30.3)。UI は 8025、SMTP は 1025。 未使用の mailcatcher-data ボリュームを削除 - agentic-commerce-e2e.yml: サービスコンテナを .github/actions/mailpit に 置き換える。4.4 では読まれない MAILER_URL を MAILER_DSN に直す - eccube-mail Skill の記述を更新し、未使用の MAILCATCHER_URL 定数を削除 refs EC-CUBE#7205 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
entry のパスワード再設定は、再設定画面が 404 になり、再設定の POST への攻撃 331 件が すべて 404 だった。 - POST /forgot への攻撃が成功するたびに再設定キーが作り直され、最初のメールから読んだ キーが古くなっていた。宛先で絞った最新のメールから読む - 再設定の POST を再生した時点で再設定が成功し、キーが消えていた。確認用のパスワードを 一致させずに送り、キーを残したまま入力エラーの画面へ攻撃を届ける。入力エラーを意図した リクエストには X-ZAP-Expect-Form-Error を付け、Smoke の Form error: の対象から外す - メールは docker-compose.yml の mailpit で受ける (前のコミットで cherry-pick)。 /view/latest.txt?query=to:<宛先> で、宛先で絞った最新のメールの本文を取得する。 ローカルのレーンでは mailpit のポートをホストへ公開しない 再設定の POST への攻撃は 331 件すべてが入力エラーの画面 (2xx) に届くようになり、 再生の失敗は 2/15 から 0/15 になった。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
coverage.sh で「通らない」だったルートのうち、認証の準備が要らないものを、 画面の流れが同じ既存のシナリオに足す。 - 管理画面: カテゴリ・規格名の編集画面、規格・規格分類の CSV 出力、特定商取引法、 メンバーの並び替え、レイアウトのプレビュー、受注の一括削除、売上グラフ、 受注の商品検索と返品・返金申請一覧のページ送り - 画像の読み込み (load) と取り消し (revert): 商品・支払方法。取り消しは別にアップロードした画像で行う - 返品・返金申請を、ブラウザと同じく添付ファイル付きの multipart で送る。 確認画面の一時ファイルと、マイページ・管理画面の添付のダウンロードを通す。 before_script は制御文字があると ZAP が読み込めないため、ASCII だけの GIF にする - フロント: 商品詳細からのお気に入り削除、購入エラー画面、保存した配送方法・支払方法の復元 (admin_create_customer.zst の購入で保存する) - 同梱プラグイン: 商品レビューの CSV 出力と設定、おすすめ商品の商品検索のページ送り。 商品レビューのページ管理用のダミーのルートは対象外にする あわせて、攻撃が画面の処理まで届いていなかった 2 シナリオを直す。 - plugin_product_review: フロントの CSRF トークンを位置 (formIndex) で取り出しており、 ヘッダーの検索フォームを指す環境ではレビューを投稿できず、後続の 8 ステップが失敗していた。 フィールド名で取り出す - plugin_recommend: 編集の POST が、記録した環境のおすすめ商品の ID を送っており、 更新処理が「見つからない」で終わっていた Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
coverage.sh で「通らない」に残っていたルートを通し、通らないルートを 0 本にする。 - admin_security: セキュリティ設定。IP 制限・SSL の強制・TRUSTED_HOSTS・管理画面のパスを docker-compose.owaspzap.ci.yml で既定値のまま環境変数に固定し、画面から保存しても .env に 書き込まれないようにして、攻撃で管理画面から締め出されないようにする - admin_member_setting: 2 段階認証の設定の完了と変更 (/two_factor_auth/edit) を足す。 コード (TOTP) は httpsender スクリプト (zap/scripts/totp.js) が送信の直前に計算する。 攻撃は誤ったコードの送信で受ける (設定が完了すると以降は転送され、フォームに届かないため)。 ログイン後の認証の画面は、ZAP が認証済みの cookie を保持して付け直すため通せず、対象外にする - admin_agent_commerce: エージェントコマースの設定画面 (ACP Feed の push、UCP Catalog のキャッシュ) - plugin_api_admin: eccube-api4 の OAuth クライアント・MCP トークン・Webhook の管理 - api_catalog: UCP Catalog (認証なしの JSON API) - api_acp_checkout / api_ucp_checkout: ACP / UCP のチェックアウト (作成・取得・更新・完了・取り消し)。 before_script (admin_enable_agent_checkout.zst) でチェックアウトを有効にし、ACP の OAuth クライアントを作る。 Idempotency-Key は httpsender スクリプト (zap/scripts/idempotency_key.js) がリクエストごとの値にする (固定のキーでは、本文を書き換えた攻撃が 422 で止まるため) - api_oauth: eccube-api4 の認可コードフロー (クライアントの登録・同意・トークン・GraphQL) と、 MCP クライアントの動的登録 (/register)。/register のレート制限は prepare_ec-cube.sh で緩める Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ZAP は anti-CSRF トークン名を部分一致 (大文字小文字を区別しない) で判定し、 該当するパラメータを能動スキャンの対象から外す。一覧の _token が mcp_token[label] などの MCP トークン発行フォームの全項目と admin_two_factor_auth[device_token] に当たり、攻撃が届いていなかった。 _token を無効にし、フォームの [_token] に絞る。一覧から消すと ZAP が既定の トークン名として足し直すため、残したまま無効にする。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 段階認証の設定への攻撃で auth_key が 1 文字などになると、鍵が空になり totp.js が例外を投げていた。ZAP は例外を投げたスクリプトを止めるため、 続く変更のステップで ZAP_TOTP が置き換わらず、再生が入力エラーになっていた。 計算できないときは置き換えずに送る。 README に、eccube-api4 の /token への攻撃が invalid_grant で止まる理由と、 このままにしている理由を書く。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要(Overview・Refs Issue)
Refs #7190
OWASP ZAP の Zest シナリオ (
zap/scripts/*.zst) を 4.4 に移行し、.github/workflows/zaproxy.ymlとローカルの両方で実行できるようにします。あわせて、4.4 で追加された機能のシナリオを追加します。_tokenの抽出、基本設定の追加項目、/help/guide、固定のECCUBE-CSRF-TOKENなど)front_loginコンテキスト、セッションの保持、thread_per_host、Path Traversal の誤検知の除外)APP_ENV=prod、バンドル版プラグインの4.4版、再生失敗の検出、ポリシーとターゲットの指定、ZAP のイメージを公式のghcr.io/zaproxy/zaproxy:stableに変更)zap/local/) と CI の共通スクリプト (zap/bin/)、zap/README.mdzap/bin/coverage.sh)、リクエストごとに攻撃が届いた件数と応答の内訳 (zap/bin/attack_counts.sh、attacks.tsv)zap/bin/lint_zst.sh。CI の Prepare matrix で実行)EC-CUBEポリシー)zap/patches/、workflow_dispatchのpatches。既定では当てない)Smokeでの入力エラーの画面の検出 (zap/scripts/report_form_errors.js)方針(Policy)
EccubeE2ePassword1にそろえています。src/・app/) には変更を加えていません。zap/以外の変更は、ワークフローと ZAP 用の Docker Compose の設定と、chore: docker-compose.yml の mailcatcher を mailpit に置き換える #7207 (docker-compose.ymlなどの mailcatcher を mailpit に置き換える) の cherry-pick です。chore: docker-compose.yml の mailcatcher を mailpit に置き換える #7207 が先にマージされれば、その分の差分は消えます。zap/bin/) を使います。ワークフローはコンテナの起動と成果物のアップロードだけを受け持ちます。zap/targets.jsonに置き、CI のマトリクスとローカル実行の両方がこれを読みます。実装に関する補足(Appendix)
Smokeポリシー (全ルール OFF) ではエラー、Sequenceポリシーでは警告として扱います (zap/bin/check_results.sh)。APP_ENV:docker-compose.ymlにAPP_ENV: "dev"が直書きされていて、これまで CI でも dev で動いていました。docker-compose.owaspzap.ci.ymlで prod に上書きしています。front_new_item: 外部サイトと_wdtへのリクエストを削除し、作成から削除までを一続きに組み直しました。コンテキストは default のままで、シナリオの中で管理画面にログインします。zap/README.mdの「既知の再生の失敗」に記載しました。delete_data.shはスキャンで作られたデータを定期的に消します。タグは作成日時を持たないため 2 周前 (10 秒以上前) からあった ID だけを、支払方法とテンプレートは作成の 1 分後に消すようにしました。作成直後に消すと、シナリオが後の手順で編集・削除する前に消えて 404 になっていたためです。attacks.tsvを比べました。効果があったのはお届け先の登録上限と削除を無効にするものだけだったため、これだけを収録しています。評価の詳細は ZAP: zst シナリオを 4.4 に移行し、4.4 の新機能をスキャン対象に加える #7190 に記載しています。----WebKitFormBoundary...) では本文を分割できず、能動スキャンの攻撃が 1 件も送られていませんでした (各スキャンルールがIndexOutOfBoundsExceptionで中断し、ZAP の内部ログにだけ出ます)。シナリオの boundary を小文字にし、boundary の行の前の改行を CRLF に揃えました。#以降とクエリ文字列に値を入れてalert()の実行を見るルールで、POST の本文やシナリオのステップの状態は扱いません。EC-CUBE の JavaScript はlocation.hash/location.searchを読んでおらず、全ターゲットのスキャンで 1 件も検出していません。一方で 1 ステップが ZAP の待ち時間の上限 (600 秒) に達することがあり、上限後もスレッドが止まらず次のルールの所要時間まで延ばしていました。同梱のSequenceポリシーは読み取り専用のため、このルールだけを OFF にしたEC-CUBEポリシーをprepare_zap.shで作ります。同梱のポリシーの<locked>(列挙していないルールを無効にする) は残しています。外すと同梱に無いルールまで有効になるためです。Smokeでは httpsender スクリプトで、入力エラーの画面が返った POST をForm error:としてログに出し、再生の失敗に数えます。再生と攻撃は ZAP の中で区別できない (どちらも能動スキャンのリクエスト) ため、Smokeに限っています。入力エラーを意図したリクエストにはX-ZAP-Expect-Form-Errorヘッダーを付けて対象から外します。POST /forgotへの攻撃が再設定キーを作り直すため、宛先で絞った最新のメールからキーを読みます (mailpit の/view/latest.txt?query=to:<宛先>)。再設定の完了でキーが消えるため、攻撃を受ける再設定の POST は確認用のパスワードを一致させずに送ります。_tokenと_methodだけで、パスの ID は ZAP の既定では攻撃されません。URL のパスを攻撃の対象に加えても、ID の\d+の制約でルーティングが 404 を返すうえ、固定の文字列のパス要素への攻撃でリクエストが増える (entryで 5,291 件から 8,564 件) ため、加えていません。before_scriptで会員の作成、購入、発送済みへの変更を行います。admin コンテキストで会員としてログインするとセッション ID が変わり管理画面が未ログイン扱いになるため、管理画面にログインし直しています。テスト(Test)
zap/local/、APP_ENV=prod、バンドル版プラグイン導入済み):Smokeで全ターゲットを再生しました。失敗はplugin_coupon_guest_shoppingの 1 本だけで、EC-CUBE 4.4 対応: 削除される OrderItem::setTaxRuleId() の呼び出しを修正する coupon-plugin#198 の不具合によるものです。Sequenceで全ターゲットをスキャンし、シナリオの再生・レポートの出力・所要時間を確認しました。SmokeとSequenceの両方で確認しました。返品・返金申請とお届け先の編集・削除は、処理が DB に反映されていることも確かめています。workflow_dispatch:Smoke: 3 ターゲットが成功。plugin_coupon_guest_shoppingは上記の不具合どおり失敗しました。Smoke: すべて成功しました。Smoke: 72 ターゲット中、失敗はplugin_coupon_guest_shopping(上記の不具合) とadmin_paymentの 2 本でした。admin_paymentは支払方法の定期削除との競合で、猶予を延ばした後に再実行して成功しました。stableに切り替えた後の全ターゲットのSmoke: 失敗はplugin_coupon_guest_shoppingだけでした。plugin_coupon_.*のSmoke: すべて成功しました。ローカルのSequenceでも購入確定まで再生できています。Smoke:lint_zst.shを含めすべて成功しました。entry・plugin_mailmagazine_send・admin_order_mail) のSmoke: すべて成功し、Form error:も出ませんでした。Smoke: すべて成功しました。Sequence): multipart のリクエスト 14 件で、EC-CUBE が受けたリクエストが 1〜3 件から 425〜4,123 件に増えました (admin_content_fileは 2 時間で打ち切った時点で 3 件から 1,840 件)。新たに見つかった 500 は 想定外の入力値で 500 になる箇所が管理画面・フロントに多数ある (入力値の型・存在の未検証) #7192 に追記しました。Sequence):plugin_mailmagazine_sendは 3 時間 3 分から 18 分、admin_paymentは 11 分から 2 分 20 秒になりました。攻撃の件数はほぼ同じで、動いたルールは同梱のSequenceからこのルールを除いた 18 本であることを ZAP のログで確かめました。Sequence):admin_product_editの再生の失敗が 6/11 から 0/11 になり、商品登録への攻撃の 500 が 676/2,079 件から 0 件になりました。パスワード再設定の POST への攻撃 331 件は、すべて 4xx だったものがすべて 2xx になりました。相談(Discussion)
マイナーバージョン互換性保持のための制限事項チェックリスト
レビュワー確認項目
🤖 Generated with Claude Code