a-blog cms PHP API Reference

SsrfGuardedClient
in package
implements ClientInterface

SSRF ガードを挟む PSR-18 クライアントのデコレーター。

委譲先のクライアントへ渡す前に取得先を検証し、リダイレクトもホップごとに 検証したうえで自前で追従する。委譲先には自動追従をさせない設定を与えること。

Table of Contents

Interfaces

ClientInterface

Constants

DEFAULT_MAX_REDIRECTS  = 10
追従を許可するリダイレクト回数の既定値
REDIRECT_STATUS_CODES  = [301, 302, 303, 307, 308]
リダイレクトとみなすステータスコード
XML_CONTENT_TYPE_NEEDLE  = 'xml'
XML と判定する Content-Type の部分一致キーワード

Properties

$guard  : SsrfGuard
$inner  : ClientInterface
$maxRedirects  : int
$uriFactory  : UriFactoryInterface

Methods

__construct()  : mixed
sendRequest()  : ResponseInterface
assertFetchable()  : array<string|int, string>
取得してよい URI か検証し、検証を通った IP アドレス一覧を返す
assertSafeXmlBody()  : ResponseInterface
oEmbed の XML 応答に DOCTYPE / ENTITY 宣言が(位置を問わず)含まれていないか検査する。
resolveRedirectUri()  : string
リダイレクト元 URI と Location ヘッダの値から絶対 URI を組み立てる

Constants

DEFAULT_MAX_REDIRECTS

追従を許可するリダイレクト回数の既定値

private mixed DEFAULT_MAX_REDIRECTS = 10

Why not: 独自に小さい値を決めないのは、それまで curl の自動追従(CURLOPT_MAXREDIRS の 既定 10)で取得できていたページが、ホップ数だけを理由に取得できなくなるのを避けるため。

REDIRECT_STATUS_CODES

リダイレクトとみなすステータスコード

private mixed REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308]

XML_CONTENT_TYPE_NEEDLE

XML と判定する Content-Type の部分一致キーワード

private mixed XML_CONTENT_TYPE_NEEDLE = 'xml'

Properties

Methods

__construct()

public __construct(ClientInterface $inner, UriFactoryInterface $uriFactory[, SsrfGuard|null $guard = null ][, int $maxRedirects = self::DEFAULT_MAX_REDIRECTS ]) : mixed
Parameters
$inner : ClientInterface

実際に HTTP 取得を行うクライアント(自動リダイレクト追従は無効にしておく)

$uriFactory : UriFactoryInterface

リダイレクト先の URI を組み立てるファクトリ

$guard : SsrfGuard|null = null

null なら既定の設定でガードを組み立てる

$maxRedirects : int = self::DEFAULT_MAX_REDIRECTS

追従を許可するリダイレクト回数の上限

sendRequest()

public sendRequest(RequestInterface $request) : ResponseInterface
Parameters
$request : RequestInterface
Tags
throws
RuntimeException

取得を許可できない URI を指している場合

Return values
ResponseInterface

assertFetchable()

取得してよい URI か検証し、検証を通った IP アドレス一覧を返す

private assertFetchable(string $uri) : array<string|int, string>
Parameters
$uri : string
Tags
throws
RuntimeException
Return values
array<string|int, string> —

検証を通った IP アドレス一覧(接続のピンニングに使う)

assertSafeXmlBody()

oEmbed の XML 応答に DOCTYPE / ENTITY 宣言が(位置を問わず)含まれていないか検査する。

private assertSafeXmlBody(ResponseInterface $response) : ResponseInterface

Why not: embed/embed 側の DOCTYPE 除去(\Embed\OEmbed::extractXML)は文字列先頭に 厳密にアンカーされた正規表現(/^<!DOCTYPE[^>]*+>/i)のため、先頭に XML 宣言や空白がある 応答では除去されずに SimpleXMLElement へそのまま渡り、Billion Laughs / Quadratic Blowup に よるメモリ枯渇(DoS)を許してしまう。ここでは HTTP レイヤーで位置を問わず検出し、 応答自体を拒否する(vendor 側の直接パッチは CMS アップデートで上書きされるため避ける)。

Parameters
$response : ResponseInterface
Tags
throws
RuntimeException

DOCTYPE / ENTITY 宣言を含む XML 応答の場合

Return values
ResponseInterface

resolveRedirectUri()

リダイレクト元 URI と Location ヘッダの値から絶対 URI を組み立てる

private resolveRedirectUri(string $baseUri, string $location) : string
Parameters
$baseUri : string
$location : string
Tags
throws
RuntimeException
Return values
string

        
On this page

Search results