wp_safe_remote_get() の使い方|説明・引数・注意点

説明

wp_safe_remote_get() は、外部のURLにGETリクエストを送る関数です。使い方は wp_remote_get() と同じですが、リクエスト先のURLを検証し、ローカルやプライベートなアドレスなど、安全でない宛先へのリクエストを拒否します。

基本構文

wp_safe_remote_get( string $url, array $args = array() ): array|WP_Error

引数

  • $url:リクエスト先のURL
  • $args:リクエストの設定(timeout、headers など)。wp_remote_get() と同じ

戻り値

成功すると、レスポンスの配列を返します。失敗すると WP_Error を返します。

使い方(サンプル)

$response = wp_safe_remote_get( $url, array( 'timeout' => 10 ) );

if ( is_wp_error( $response ) ) {
	return; // 失敗(安全でないURLとして拒否された場合も含む)
}

$body = wp_remote_retrieve_body( $response );

注意点

  • URLをユーザーの入力や、管理画面の設定値から受け取る場合は、wp_remote_get() ではなくこちらを使います。サーバーの内部にあるアドレスへ、外部の入力でリクエストを送らされる攻撃(SSRF)を防ぐためです。
  • 宛先が、プライベートやループバックなどのIPアドレス(またはそれに解決されるホスト名)の場合は、拒否されて失敗します。ただし、サイト自身のホスト(home と同じホスト)は対象外です。自分で管理している固定のURLであれば、wp_remote_get() を使います。
  • ほかにも、http・https 以外のスキーム、ユーザー名やパスワードを含むURL、80・443・8080以外のポートは拒否されます(許可するポートは http_allowed_safe_ports フィルターで変更できます)。リダイレクト先のURLも検証されます。
  • 戻り値が WP_Error かどうかの判定は、必ず行います。
  • SSRF対策の一助ですが、万能ではありません。URLを検証してから、リクエストしますが、DNSの再解決などによる攻撃までは、防げません。外部の入力で宛先が変わる機能では、許可するホストを、自分で絞るなどの対策も行います。

実務での使いどころ

  • 管理画面の設定欄に、ユーザーが入力したURLからデータを取得する機能。
  • フォームで受け取ったURLの内容(タイトルなど)を取得する処理。
  • 外部の入力で宛先が変わる、あらゆる外部リクエスト。

よくあるミスと対処

  • ユーザー入力のURLを、そのまま wp_remote_get() に渡している。宛先を検証しないため、内部のアドレスに到達できてしまいます。
  • ローカル環境のURLを呼んで失敗し、原因が分からない。拒否されたときのエラーメッセージは、「安全でない」とは表示されず、汎用的な内容になります。URLが上の条件に当てはまらないか、確認します。

NG例

// 入力されたURLを、そのまま取得している
$response = wp_remote_get( $_POST['url'] );

OK例

$url = isset( $_POST['url'] ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : '';
$response = wp_safe_remote_get( $url );

使い分け早見表

関数 使う場面
wp_remote_get() 宛先が固定で、自分で管理しているURL
wp_safe_remote_get() 宛先が、ユーザー入力や設定値で変わるURL

関連項目

wp_remote_get()、wp_remote_retrieve_body()、set_transient()

公式リファレンス:wp_safe_remote_get() | WordPress Developer Resources

コメント

タイトルとURLをコピーしました