Skip to content

Feature/fix zap ZAPのバージョンアップに対応#6619

Open
zeniya0000 wants to merge 169 commits intoEC-CUBE:4.3from
zeniya0000:feature/fix_zap
Open

Feature/fix zap ZAPのバージョンアップに対応#6619
zeniya0000 wants to merge 169 commits intoEC-CUBE:4.3from
zeniya0000:feature/fix_zap

Conversation

@zeniya0000
Copy link
Contributor

@zeniya0000 zeniya0000 commented Feb 11, 2026

概要(Overview・Refs Issue)

OSSのGitHub Actionsで使用している OWASP ZAP のバージョンが古いため、最新バージョンでスキャンが実行されるよう環境の刷新を行いました。

変更内容

最新バージョンの利用に伴い、依存関係およびイメージの管理方法を以下の通り変更しています。

  1. ZAP本体とzap-extensionsのバージョンアップ
    ・セキュリティスキャンの精度向上と最新の脆弱性への対応のため。
  2. JDKのバージョンアップ
    ・上記ZAPのアップデートに伴い、動作要件を満たすJDKバージョンへ更新。
  3. Dockerイメージの参照先変更
    ・外部リポジトリから取得していたイメージを、ec-cube 本体のGitHub(GitHub Packages)内へ移行

動作確認

事前に以下の個人リポジトリにて動作確認を行っています。
1回目:https://github.com/zeniya0000/ec-cube/actions/runs/21889773054
2回目:https://github.com/zeniya0000/ec-cube/actions/runs/21892209250
※一度で回りきっていないので、1回目でまわりきらなかったものを2回目でまわしています。

マイナーバージョン互換性保持のための制限事項チェックリスト

  • 既存機能の仕様変更はありません
  • フックポイントの呼び出しタイミングの変更はありません
  • フックポイントのパラメータの削除・データ型の変更はありません
  • twigファイルに渡しているパラメータの削除・データ型の変更はありません
  • Serviceクラスの公開関数の、引数の削除・データ型の変更はありません
  • 入出力ファイル(CSVなど)のフォーマット変更はありません

レビュワー確認項目

  • 動作確認
  • コードレビュー
  • E2E/Unit テスト確認(テストの追加・変更が必要かどうか)
  • 互換性が保持されているか
  • セキュリティ上の問題がないか
    • 権限を超えた操作が可能にならないか
    • 不要なファイルアップロードがないか
    • 外部へ公開されるファイルや機能の追加ではないか
    • テンプレートでのエスケープ漏れがないか

Summary by CodeRabbit

  • 新機能

    • セキュリティスキャンワークフロー拡張(事前スクリプト注入、プリプロセス、アドオン管理、自動実行、詳細デバッグ)
    • スキャン用コンテナの起動設定・エントリポイント追加とヘルス監視改善
  • バグ修正

    • レポート/アラートの収集・マージ処理を堅牢化(欠損検出・失敗時のログ取得)
    • 非対話モード操作とデータ投入の検証を強化
  • Chores

    • テスト用データシードと一括初期化の導入
    • ワークフロー手順の整理と可視性向上(パッチ適用・検証フロー追加)

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

OWASP ZAP テストワークフローを拡張し、GitHub Actions ワークフロー、docker-compose 設定、ZAP 自動化テンプレートと関連スクリプト(シード/削除/生成)を更新して、非対話実行・before_script パッチ挿入、アドオン更新、Zest 前処理、alerts マージとアーティファクト処理を追加しています。

Changes

Cohort / File(s) Summary
GitHub Actions ワークフロー
/.github/workflows/zaproxy.yml
ステップ名更新と多数追加:EC-CUBE イメージビルド/アップロード/ダウンロード、docker-compose を非対話(-T)で実行、DB シード/検証、ZAP コンテナデバッグ/アドオン更新、Zest 前処理、autorun 非対話化、before_script 用 YAML パッチ挿入、alerts マージ改善、アーティファクトアップロードを v4 に切替(上書き有効)。
Docker 構成
docker-compose.owaspzap.ci.yml
zap イメージを ghcr.io/ec-cube/zaproxy:0.1.2 に更新。entrypoint/command 追加で常駐化、HOME 環境変数追加、ポリシーパスを読み取り専用へ変更、ヘルスチェック間隔・タイムアウト・リトライ・start_period を調整。
ZAP 自動化テンプレート
zap/automation/template.yml
認証/ログアウト検証を pollUrl ベースに切替、loggedOutRegex 更新、ジョブを script 系から sequence-activeScan へ統合(構造変更)。
データ管理スクリプト
zap/delete_data.sh, zap/seed_zap.sql
delete_data.shset -euo pipefail を追加し、ループ削除から TRUNCATE/RESTART IDENTITY による一括リセットへ変更。新規 seed_zap.sql を追加し dtb_customer の初期レコード挿入とシーケンス同期を実装。
自動化設定生成スクリプト
zap/generate_automation_config.sh
admin 強制設定を無効化(空文字化)、ZA_BEFORE_SCRIPT の拡張子判定(.zst)に基づき before_script 実行ブロックを条件付きで生成するロジックに変更。
補助処理 / ZAP 関連ファイル
zap/...
Zest トークン置換処理、alerts.json の検出・結合ロジック刷新、ZAP デバッグログ取得ステップなど補助処理を追加・修正。

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant EC as EC-CUBE Container
    participant DB as Database
    participant ZAP as ZAP Container
    participant AR as Artifact Store

    GH->>EC: build/download EC-CUBE image & start (docker-compose exec -T)
    GH->>DB: apply seed SQL (`zap/seed_zap.sql`) and prepare DB
    GH->>EC: run non-interactive setup/seed/verify commands (-T)
    GH->>ZAP: start ZAP container (entrypoint tail -f /dev/null)
    GH->>ZAP: patch automation config (insert before_script)
    GH->>ZAP: install add-ons / preprocess Zest (token replacement)
    GH->>ZAP: autorun scans (non-interactive)
    ZAP-->>GH: emit reports & alerts
    GH->>AR: upload reports & zap-*-alerts artifacts (v4, overwrite)
    GH->>GH: download zap-*-alerts artifacts and merge -> all_alerts.json
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • nanasess
  • ji-eunsoo

Poem

🐰 ぴょんと飛んでワークフロー整え、
シード撒きコンテナを抱えて、
Zest の糸をそっと繕い、
レポート抱えて跳ねるよ、
小さな足跡、今日も進む ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルはZAPのバージョンアップ対応という変更内容の主要な目的を的確に反映しており、変更セット全体の中心的な意図を明確に要約しています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/zaproxy.yml (1)

26-26: ⚠️ Potential issue | 🟠 Major

actions/checkout@master はセキュリティリスク

@master は可変参照であり、上流リポジトリへの不正コミットによるサプライチェーン攻撃のリスクがあります。Line 166も同様です。タグ(例: @v4)またはコミットSHAにピン留めしてください。

提案
-        uses: actions/checkout@master
+        uses: actions/checkout@v4
🤖 Fix all issues with AI agents
In @.github/workflows/zaproxy.yml:
- Around line 222-237: The workflow never uses matrix-provided before scripts
because the override that assigns ZAP_BEFORE_SCRIPT to BEFORE is commented out;
either uncomment the line "if [[ -n \"${ZAP_BEFORE_SCRIPT:-}\" ]]; then
BEFORE=\"${ZAP_BEFORE_SCRIPT}\"; fi" so ZAP_BEFORE_SCRIPT (from
matrix.before_script) is applied before invoking
zap/generate_automation_config.sh (references: ZAP_BEFORE_SCRIPT, BEFORE, and
the zap/generate_automation_config.sh call), or if matrix.before_script entries
are not needed remove them from the matrix to avoid confusion.
- Line 235: 現在の展開 `${BEFORE:+"-b ${BEFORE}"}` は展開結果が一括した引数(例: "\"-b
admin_login.zst\"")になる可能性があるので、安全に分割した引数を渡すよう修正してください;例えば展開中にクォートを文字列として残さない形
`${BEFORE:+-b "$BEFORE"}` に置き換えるか、より明示的に if [ -n "$BEFORE" ]; then ARGS+=("-b"
"$BEFORE"); fi のように `-b` と値を別々の引数として追加する実装(変更箇所は `${BEFORE:+"-b ${BEFORE}"}`
を含む該当行)にしてください。
- Line 41: The workflow mixes different major versions of the artifact actions;
update every occurrence of actions/upload-artifact to the same major version
(use v6) and every occurrence of actions/download-artifact to the same major
version (use v7) so artifact upload/download calls are consistent; search for
all uses of "actions/upload-artifact" and "actions/download-artifact" in the
file and replace their version tags (e.g., v4/v5/v6/v7) accordingly, then run a
quick workflow lint to ensure no syntax/compatibility issues remain.

In `@zap/automation/template.yml`:
- Around line 64-68: The matrix's thread_per_host setting is being collected
into ZA_THREAD_PER_HOST by generate_automation_config.sh but not applied because
the job uses type: sequence-activeScan which doesn't propagate thread_per_host;
change the job to use the scanner job type that accepts per-scan thread settings
(e.g., activeScan) or add the supported parameter name (threadPerHost) to the
parameters block and bind it to ${ZA_THREAD_PER_HOST}; update template.yml's
sequence-activeScan entry (or replace it with activeScan) and ensure
generate_automation_config.sh still sets ZA_THREAD_PER_HOST so the threadPerHost
value is passed into the scan execution.

In `@zap/seed_zap.sql`:
- Line 52: シードデータの顧客ステータスが現在
customer_status_id=1(仮会員)になっており、認証が必要な画面(front_mypage、mypage_order
等)にアクセスできないためテストが失敗します;seed_zap.sql の該当レコードで customer_status_id を 1 から
2(本会員/ACTIVE)に変更して、ログイン可能な状態にしてテストが通るようにしてください。
🧹 Nitpick comments (2)
zap/generate_automation_config.sh (1)

44-52: .zst ファイルの場合に run ブロックを追加しない理由が不明確

.zst(Zestスクリプト)の場合、ここでは run ブロックが追加されませんが、ワークフロー側の「Patch automation config」ステップ(Python スクリプト)で後から run ブロックが挿入されます。このロジックが2箇所に分散しているため、保守性が低下しています。

なぜ .zst の場合だけワークフロー側でパッチする必要があるのか、コメントで意図を明記することを推奨します。

zap/delete_data.sh (1)

14-37: コメントアウトされた旧コードを削除してください

20行以上のコメントアウトコードはバージョン管理で履歴が残るため、削除して可読性を向上させることを推奨します。

@zeniya0000 zeniya0000 changed the title Feature/fix zap Feature/fix zap ZAPのバージョンアップに対応 Feb 12, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/zaproxy.yml:
- Around line 328-350: The "Debug zap logs after autorun" step runs docker
compose exec -T zap cat /home/zap/.ZAP/zap.log which will fail the step if
zap.log is missing; update this step to first check for the file (e.g., test -f
/home/zap/.ZAP/zap.log inside the container) and only run the cat when it
exists, or fall back to a no-op (or use a command that returns success on
missing files) so the debug step does not error out when /home/zap/.ZAP/zap.log
is absent.
- Around line 387-397: The current merge command jq -s 'add' assumes every
alerts.json is a valid JSON array; instead validate and filter files first:
using the existing file list (from mapfile/find) run each file through jq -e
'type == "array"' (or equivalent) and only pass the successfully-validated files
to jq -s 'add' to produce all_alerts.json (or use a single jq invocation like jq
-s 'map(select(type=="array")) | add' over the files); if no valid arrays
remain, fail with a clear error instead of producing an invalid/empty
all_alerts.json. Ensure you reference the variables/files produced by
mapfile/find and write to all_alerts.json as before.
🧹 Nitpick comments (4)
.github/workflows/zaproxy.yml (4)

241-293: Python によるYAML パッチ処理 — 正規表現ベースのYAML操作はフラジャイル

正規表現でYAMLを編集するアプローチは、テンプレートのインデントやフォーマットが変わると容易に壊れます。現時点では動作しているかもしれませんが、将来的なメンテナンスコストが高くなります。

いくつかの懸念点:

  1. Line 267-276: 正規表現パターンがインデントに厳密に依存しています。テンプレートのフォーマットが少しでも変わるとマッチしなくなり、Line 278 で SystemExit が発生します。
  2. Line 280-286: 挿入する YAML フラグメントもハードコードされたインデントに依存しています。

将来的には ruamel.yamlpyyaml を使ったパース・編集への移行を検討してください。現時点ではCIで追加パッケージのインストールを避ける意図であれば許容範囲ですが、テンプレートとの密結合はリスクです。


302-308: ZAP Add-on の更新・再インストール手順について

sequence アドオンを一度アンインストールしてから再インストールしています。これは最新版を確実にインストールする意図と思われますが、-addonupdate は既にインストール済みアドオンを更新するはずです。

また、各 -cmd 呼び出しで ZAP が毎回起動・終了するため、この4ステップでかなりの時間がかかる可能性があります。パフォーマンスが問題になる場合は、複数のアドオン操作を1回の起動にまとめることを検討してください。


226-226: matrix.target をシェル比較で直接展開するのはインジェクションリスク

${{ matrix.target }} はワークフロー定義内の固定値なので現時点では問題ありませんが、GitHub Actions のベストプラクティスとして、式展開を環境変数経由で渡す方が安全です。Line 234, 331, 340 等でも同様のパターンが使われています。

🔧 修正案(Line 226 の例)
+        env:
+          TARGET: ${{ matrix.target }}
         run: |
           set -eu
           BEFORE=""
-          if [[ "${{ matrix.target }}" == admin_* ]]; then
+          if [[ "${TARGET}" == admin_* ]]; then
             BEFORE="admin_login.zst"
           fi

189-192: シードデータの冪等性は部分的に担保されています

seed_zap.sqlDELETE FROM dtb_customer WHERE id = 1; で既存レコードを削除した後に INSERT しているため、基本的な冪等性は実装されています。ただし、この方式は以下の点で脆弱です:

  • DELETE が成功しても INSERT が失敗した場合、シーケンスだけ更新される可能性がある
  • 単一レコード削除のため、部分的な失敗に対して堅牢ではない

より堅牢な実装としては、INSERT ... ON CONFLICT DO UPDATE SET または TRUNCATE での全削除 + INSERT を検討してください。現在の実装は機能しますが、ワークフロー再実行時の信頼性を高めるため、上記パターンへの改善が望ましいです。

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/zaproxy.yml:
- Around line 295-300: The debug steps using docker compose exec (the commands
invoking whoami, pwd, ls -l /zap/wrk, and ls -l /home/zap/.ZAP || true) are
missing the non-interactive -T flag; update each docker compose exec invocation
in that block to include -T (e.g., docker compose exec -T ...) so the commands
run without requiring a TTY in CI and avoid hangs/warnings.
- Around line 236-237: 展開時にリテラルのダブルクォートが混入する恐れがあるため、既に修正された `${BEFORE:+-b
"${BEFORE}"}` と同じクォーティング規則を `ZAP_CONTEXT` と `ZAP_THREAD_PER_HOST`
の条件付き展開にも適用してください;具体的には `${ZAP_CONTEXT:+"-c ${ZAP_CONTEXT}"}` と
`${ZAP_THREAD_PER_HOST:+"-n ${ZAP_THREAD_PER_HOST}"}` をそれぞれ `${ZAP_CONTEXT:+-c
"${ZAP_CONTEXT}"}` と `${ZAP_THREAD_PER_HOST:+-n "${ZAP_THREAD_PER_HOST}"}`
に置き換えて、展開結果に余分なダブルクォートが含まれないように修正してください。
🧹 Nitpick comments (1)
.github/workflows/zaproxy.yml (1)

241-293: YAML パッチ処理は妥当ですが、正規表現の脆さに注意してください

正規表現によるYAMLパッチはテンプレートのインデントやフィールド順序に厳密に依存しています。テンプレート (template.yml) が変更された場合、パッチが無言で失敗する代わりに Line 278 でエラー終了するのは適切です。

将来的にテンプレート変更が頻繁になる場合は、pyyamlruamel.yaml 等のYAMLライブラリの使用を検討してください。

@EC-CUBE EC-CUBE deleted a comment from coderabbitai bot Feb 12, 2026
@EC-CUBE EC-CUBE deleted a comment from coderabbitai bot Feb 12, 2026
@codecov
Copy link

codecov bot commented Feb 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.83%. Comparing base (37c5250) to head (d31be8d).
⚠️ Report is 1 commits behind head on 4.3.

Additional details and impacted files
@@             Coverage Diff              @@
##                4.3    #6619      +/-   ##
============================================
- Coverage     78.84%   78.83%   -0.01%     
  Complexity     6631     6631              
============================================
  Files           475      475              
  Lines         26539    26539              
============================================
- Hits          20924    20923       -1     
- Misses         5615     5616       +1     
Flag Coverage Δ
Unit 78.83% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- mypage_delivery
- mypage_favorite
- mypage_order
# - admin_class_category_csv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントアウトされたターゲットがありますが、一時的なものであればその旨のコメントを記載してください。
恒久的なものであれば削除してください

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

試験用の一時的なコメントアウトだったため、コメントアウトを外しました。

delete from dtb_tag where id > ${MAX_TAG_ID};";
sleep 5
done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントアウトしている理由を記載してください。恒久的なものであれば削除してください

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

恒久的なものであるため削除いたしました。


MAX_MEMBER_ID=$(psql -t -c 'select max(id) from dtb_member;')
MAX_TAG_ID=$(psql -t -c 'select max(id) from dtb_tag;')
psql -v ON_ERROR_STOP=1 <<'SQL'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

何故コメントアウトされている delete from ではなく、一部のテーブルに限定した TRUNCATE にしているか理由を記述してください

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

シーケンステストの使うテーブルによってはここで削除することでスキャンが出来ない部分などがあったため省いています。
(すみません、具体的な原因までは突き止められていません)

ZA_CONTEXT=admin
ZA_USER=admin
ZA_FORCE_ADMIN_CONFIG="
- type: script
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これらのスクリプトを削除している理由を記載してください。
もし不要になったのであれば forceuser.groovy も削除してください

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要であるためforceuser.groovy含めて削除いたしました。

docker compose exec -d -e PGUSER=dbuser -e PGDATABASE=eccubedb postgres /delete_data.sh
docker compose exec -T -e PGUSER=dbuser -e PGDATABASE=eccubedb postgres bash /delete_data.sh
docker compose cp zap/seed_zap.sql postgres:/
docker compose exec -T -e PGUSER=dbuser -e PGDATABASE=eccubedb postgres psql -f /seed_zap.sql
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seed_zap.sql は 1件 dtb_customer を INSERT しているのみなので、この程度であれば bin/console doctrine:query:sql コマンドを使用し、 PostgreSQL/MySQL を抽象的に利用できるようにしてください

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seed_zap.sql自体が不要でしたので、該当部分とseed_zap.sql自体を削除いたしました。

@zeniya0000 zeniya0000 marked this pull request as draft February 13, 2026 04:20
@zeniya0000 zeniya0000 marked this pull request as ready for review February 13, 2026 05:00
@zeniya0000 zeniya0000 marked this pull request as draft February 13, 2026 05:01
@zeniya0000 zeniya0000 marked this pull request as ready for review February 13, 2026 06:14
@nanasess
Copy link
Contributor

PR #6619 コードレビュー: ZAPバージョンアップ対応

ZAP環境を kiy0taka/zap2docker-eccube から ghcr.io/ec-cube/zaproxy:0.1.2 に移行し、Automation Frameworkのジョブタイプを sequence-activeScan(ZAP 2.16.0+対応)に変更、各Zestスクリプトにログインシーケンスを直接埋め込む大規模な変更です。


1. バージョンアップの適切性

概ね適切だが、いくつか懸念あり

  • sequence-activeScan は ZAP 2.16.0 の Sequence Scanner アドオンで導入された正式なジョブタイプ(公式ドキュメント確認済み)
  • Dockerイメージを ghcr.io/ec-cube/zaproxy に移行する判断は、管理の内部化として妥当

問題点:

  • threadPerHost パラメータが無効化されている: generate_automation_config.sh-n オプションで ZA_THREAD_PER_HOST を受け取り、ワークフローのmatrixでも thread_per_host: 1 を指定しているジョブがあるが、sequence-activeScan にはこのパラメータが存在しない。以前 thread_per_host: 1 で制限していた重いターゲット(admin_product_edit_class, admin_order_list 等)のスレッド制御が効かなくなっている。対策として activeScan-config ジョブを sequence-activeScan の前に追加すべき

  • ポリシーのマウントパスが変更: ./zap/policies:/home/zap/.ZAP/policies/./zap/policies:/zap/policies:ro に変更されているが、ZAPが通常 /home/zap/.ZAP/policies/ を参照するため、カスタムスキャンポリシーが認識されない可能性がある


2. スキャンの適切性に関する懸念

2a. Forced User Mode の無効化(重大)

旧実装では forceuser.groovy により ZAP の Forced User Mode をグローバルに有効化していた:

forceUser.setForcedUser(admin.getContextId(), admin)
forceUser.setForcedUserModeEnabled(true)

新実装では ZA_FORCE_ADMIN_CONFIG=""forceuser.groovy の読み込み自体を削除 し、代わりに sequence-activeScanuser: admin パラメータと template.yml の authentication verification(poll方式)に依存している。

Forced User Mode と user パラメータ + poll verification は別の仕組み:

Forced User Mode user パラメータ + poll verification
検知タイミング 毎リクエスト(プロアクティブ) 1000リクエスト毎(リアクティブ)
再認証 セッション切れ→即再認証→リクエスト送信 次のポーリングまで未認証リクエストが流れ続ける
スコープ ZAP全体(全リクエスト) 当該ジョブのみ

pollFrequency: 1000 / pollUnits: 'requests' なので、最大1000リクエスト分は未認証状態(=ログインページをスキャンしてしまう状態)が続く可能性がある。EC-CUBE の管理画面はCSRF検証でセッションが頻繁に切れるため、これは実質的に 多くのリクエストがログインページに対するスキャンになる ことを意味する。

CIランで大半のジョブが「成功」していても、成功=正しくスキャンできているとは限らない。ログインページの200応答をスキャンしてもZAPのシーケンスとしてはエラーにならず成功と報告される。スキャンレポートの中身(スキャン対象URLの分布)を確認しないと、管理画面の各機能が本当にスキャンされたのか判断できない。

対応案: forceuser.groovy の仕組みを維持すべき。ZAP 2.16+ で内部API(ExtensionForcedUser)に変更がないか確認した上で、generate_automation_config.shZA_FORCE_ADMIN_CONFIG に forceuser.groovy の add+run を戻すのが最もリスクが少ない。

2b. ログインの二重実行

全管理画面スクリプトでログインが重複する構造になっている:

  1. ワークフロー zaproxy.yml で admin_* ターゲットに対して BEFORE="admin_login.zst" が自動設定される
  2. generate_automation_config.shbefore_script として admin_login.zstadd ブロックを生成
  3. Python パッチステップが run ブロックを注入
  4. 各 admin_*.zst の先頭にも同じログインシーケンスが埋め込み済み

結果として、ログインが2回実行される。致命的ではないがスキャン時間が無駄に増加する。

2c. admin_customer_delivery.zst の三重ログイン

このスクリプトは特に問題が大きく、スクリプト内に2回のログインシーケンスが含まれている:

  • index 1-4: 標準的な4ステップログイン
  • index 5-10: コメント「【CI対策】ここで管理画面ログインを確実に実施」として追加の6ステップログイン

before_script と合わせると3回のログインが実行される。

2d. {{customer-id}} のトークン置換問題

ワークフローの "Preprocess Zest scripts" ステップで:

find /zap/wrk/scripts -name "*.zst" -print0 | xargs -0 sed -i "s/{{customer-id}}/1/g"

.zst ファイル内の {{customer-id}} を一律 1 に置換している。しかし一部スクリプト(admin_customer_delivery.zst, admin_create_customer.zst, admin_order_mail.zst)は ZestAssignStringDelimiters で customer-id を動的に抽出する仕組みがある。sed で事前に 1 に固定されるため、動的抽出が意味をなさない。

TRUNCATE ... RESTART IDENTITY で ID が1から振り直されることに依存した設計であり、極めて脆弱

2e. urlTokenurl の不整合

admin_customer_delivery.zst 内:

"url": "https://ec-cube/admin/customer/1/edit",
"urlToken": "https://ec-cube/admin/customer/{{customer-id}}/delivery/new",

url(customer edit ページ)と urlToken(delivery new ページ)が異なるURLを指している。urlToken が優先されるため意図しないページをリクエストする可能性がある。


3. delete_data.sh TRUNCATE化の問題

旧実装

  • while true; sleep 5; done の無限ループで スキャン中も継続的に データをクリーニング
  • 対象テーブル(15テーブル): dtb_page_layout, dtb_page, dtb_delivery_fee, dtb_payment_option, dtb_delivery, dtb_payment, dtb_block_position, dtb_block, dtb_layout, dtb_category, dtb_class_category, dtb_class_name, dtb_member, dtb_template, dtb_tag
  • create_date の時間範囲で最近作成されたデータのみ削除(初期フィクスチャは保持)
  • -d フラグでバックグラウンド実行

新実装

  • 1回だけ 実行(バックグラウンドではない)
  • 対象テーブル(4テーブル): dtb_customer, dtb_customer_address, dtb_order, dtb_order_item
  • TRUNCATE ... RESTART IDENTITY CASCADE で全件削除

問題点

  1. マスターデータのクリーニングが消失: ZAPのアクティブスキャンは大量のゴミデータ(ページ、レイアウト、ブロック、配送方法、支払方法、カテゴリ、規格など)を生成する。旧スクリプトはこれらを5秒おきに掃除していたが、新スクリプトでは一切クリーニングされない

  2. 初期フィクスチャの消失: TRUNCATE は全データを削除する。旧スクリプトは create_date 範囲と初期ID以降のフィルタで初期フィクスチャを保持していた。新スクリプトでは dtb_customer が空になるため、顧客データに依存するスクリプトは自前で顧客作成が必要になる(一部対応済みだが全スクリプトで確認が必要)

  3. スキャン中のデータ蓄積: アクティブスキャンが大量のリクエストを発行し、DB内にゴミデータが蓄積し続ける。これがスキャンの後半で予期しない挙動を引き起こす可能性がある


4. インデックスの不整合

admin_order_mail.zst のインデックス 31 重複

index: 31 が2箇所で使用されている(csrf6 と「出荷情報」コメント)

admin_customer_list.zst のインデックス不整合

ログイン追加後、既存のコメント「会員一覧」の index が 1 のままで、追加されたログインの index 1-4 と衝突している。


5. 良い変更点

項目 詳細
artifact名の修正 旧: report/alerts 両方 zap-*-report → 新: 別名に修正。バグ修正として良い
alerts マージの改善 jq -s 'add // []'mapfile による堅牢化
-it-T CI(非対話)環境で正しい変更
set -eu の追加 エラー検出の強化
entry.zst の改良 \n\r?\nZestAssignReplace による改行コード正規化は適切
ECCUBE-CSRF-TOKEN ハードコード除去 admin_create_customer.zst からハードコードされた CSRF トークンヘッダを除去。重要な修正
loggedOutRegex の改善 旧: HTML構造依存 → 新: name="login_id" でより堅牢

6. 総合評価・推奨事項

マージ前に対応すべき事項(Must):

  1. forceuser.groovy(Forced User Mode)の仕組みを維持する。ZAP 2.16+ での動作を確認の上、generate_automation_config.sh で復活させる
  2. delete_data.sh にマスターデータのクリーニングを追加するか、スキャン中にバックグラウンドで実行する旧方式を復活させる
  3. admin_order_mail.zst のインデックス 31 重複を修正
  4. admin_customer_delivery.zst の二重ログインと urlToken/url 不整合を修正
  5. CIランのスキャンレポートを確認し、実際に管理画面の各機能(ログインページではなく)がスキャンされていることを検証する

推奨事項(Should):

  1. admin_customer_list.zst のインデックス不整合を修正
  2. threadPerHost の制御を activeScan-config ジョブで復活させる
  3. ポリシーのマウントパスが ZAP に認識されることを確認
  4. ログインの二重実行について、before_script と埋め込みのどちらかに統一する(保守性の観点から admin_login.zst as before_script に統一し、各スクリプトからは埋め込みを除去するのが望ましい)
  5. {{customer-id}} の sed 一括置換をやめ、TRUNCATE ... RESTART IDENTITY に依存しない動的ID取得に統一する

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants