WordPress 7.0 でカスタム HTML の仕様が変わりました。
WordPress 7.0 の環境でレンタルサーバーなど共有サーバーで全体にBASIC 認証をかけたテスト・ステージング環境でカスタム HTML ブロックのプレビューが壊れることがありました。
6.9 以前でもなにかしら発生していたかもしれません。
WordPress のブロックエディターはiframe 化が進んでおり、その影響でプレビューのレスポンスが401になってしまったのではないかと思います。
今回の事象は直接iframe が要因というよりカスタム HTML ブロックのプレビュー生成時にWordPress が行うHTTP リクエストの中でBASIC 認証が弾かれるというあれです。
どうしてブロックエディターはiframe 化を進めているのかが気になる人は以下の記事を参照してみてください。
Migrating Blocks for iframe Editor Compatibility
https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/block-migration-for-iframe-editor-compatibility/
カスタムHTML ブロックのプレビューはsrcdoc 属性でコンテンツを直接iframe に流し込む仕組みのようです。
iframe 自体が 401 になるわけではなく、srcdoc の中身の<style>の中にレンタルサーバーの401ページのHTML が出力されていました。
今回発生した環境ではサーバーサイドで CSS を取得しにいくときのHTTP リクエストにBASIC 認証の認証情報が付かないためレンタルサーバーが 401 を返してしまい、エラーページのHTML がそのまま<style>に出力してしまっているというものでした。
対処
.htaccess ファイルの編集はWeb サイトが表示されなくなるリスクを伴います。
編集前に必ずバックアップを取ってから作業してください。
レンタルサーバーの設定によっては使えない記述があるかもしれません。
.htaccess に以下を追加します。
AuthType Basic
AuthName "Staging"
AuthUserFile /path/to/.htpasswd
SetEnvIf User-Agent "^WordPress/" wp_internal
<RequireAny>
Require valid-user
Require ip 127.0.0.1 ::1
Require env wp_internal
</RequireAny>
<RequireAny> で「IP 一致」「認証通過」「UserAgent 一致」のいずれかを満たせばアクセスできるようになります。
WordPress のサーバーサイドHTTP リクエストは WordPress/*** というUserAgent を使われることがあるので、SetEnvIf で拾ってAllow しています。また127.0.0.1 / ::1 はサーバーローカルから実行される場合があるので内部処理への配慮で追加しています。
セキュリティ的な話
UserAgent 制限は気持ち程度のセキュリティレベルだと思っておいてください。
SetEnvIf User-Agent "WordPress" は偽装が容易です。
curl に --user-agent "WordPress/7.0" などをつければバイパス可能です。
あくまで「WordPress の内部処理を通すための便宜的な記述」であって、セキュリティ的な強度はほぼありません。
これは強い対策ではなく、あくまでテスト・ステージング環境でWordPress の内部処理を通すための便宜的な回避策と思っておいてください。
今回発生した環境では WordPress のサーバーサイドのHTTP リクエストのUser-Agent は WordPress/*** だったのでSetEnvIf で許可しましたが、お使いの環境に合わせて変更する必要があるかもしれません。
同一サーバー内からはBASIC 認証が効かなくなります
Require ip 127.0.0.1 ::1を追加すると同じレンタルサーバーの共有サーバーに同居している他ユーザーのサーバーサイド処理からのリクエストも通るようになります。
同居ユーザーが意図的に127.0.0.1 からリクエストを投げればBASIC 認証をバイパスできるということです。
ただそれは
「BASIC 認証以前の問題」 です。
共有サーバーの同居ユーザーに悪意のあるコードを実行する権限があるなら、その他の手法でそもそもBASIC 認証以外にも様々なリスクがあります。
BASIC 認証はあくまで「うっかりアクセス」を防ぐためのものであって、本番の機密データを共有サーバーのステージング環境に置くのはそもそも推奨できません。
補足
ステージング環境で本番の機密データを扱っていないなら、実用上は問題ないですがご利用は自己責任でお願いします。
固定IP が確保できる場合はRequire ip XXX.XXX.XXX.XXXなどでIP 制限を追記して強度をあげてください。
おわりに
テスト・ステージング環境にかけたBASIC 認証が WordPress 自身の内部処理を阻んでいるのをみるとなるほどなと。
DevTools の Network タブを眺めても何も出てこないので「なぜ???」となるやつです。
レンタルサーバーやApache の設定によっては別の原因で401になることもありえるかと思いますのでご注意の上自己責任でお願いします。
同じ状況にハマっている方の助けになれば幸いです。
誤りがあれば教えてください。
ありがとうございました。