is_email()関数に渡す前にメールアドレスをサニタイズする必要がありますか?


13

私が使用しているis_email()ユーザが提供する電子メールアドレスが有効であるかどうかを確認します。例えば:

$email = $_POST['email'];
if ( is_email( $email ) )
    // Do something.

私の知る限り、この関数ではデータベースに情報を書き込みません。$email関数に渡す前にサニタイズする必要がありますか?


カイザー、編集してくれてありがとう。それは実際に私にとっては消毒です、しかし、私はここのほとんどの読者がzを使用することを確信しています:)
henrywright 14年

回答:


5

is_email()trac の機能を見ると、単なる文字列テストであるため、sanatizieを使用する必要はないようです。この関数がtrueを返した場合、データベースに送信する前にサニタイズする必要はないと言うことさえ言えます。


文字列テストについての私の考え。データベースに送信する前にまだサニタイズすると思いますが、おそらく必要ではないでしょうが、これらのことになると私は緊張します:)
henrywright 14年

確かに、申し訳ありませんが安全であり、消毒のオーバーヘッドはまったく気付かないでしょう。
Howdy_McGee

18

WordPressとPHPコア

is_email()機能ソースは、一般的なWordPressの実装であり、何で完全に動作しないRFC 6531ができます。その理由の1つは、インターネット技術特別調査委員会(IETF®)のガイドラインに従って、デフォルトのPHP FILTER_VALIDATE_EMAIL定数filter_var()が何かを検証するのにそれほど優れていないことです。

基準

ポイントは、RFC 6531「ASCII範囲を超えるUnicode文字」を許可することです。つまり、それらは(ローカル部分-の前@):

  • 大文字と小文字の英字(a〜z、A〜Z)(ASCII:65〜90、97〜122)
  • 数字09(ASCII:48〜57)
  • これらの特殊文字: ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • 文字.(ドット、ピリオド、ピリオド)(ASCII:46)は、最初または最後の文字ではなく、連続して表示されない(たとえばJohn..Doe@example.com許可されていない)ことを条件とします。
  • 特殊文字は制限付きで許可されます。彼らです:
    • スペースおよび"(),:;<>@[\](ASCII:32、34、40、41、44、58、59、60、62、64、91〜93)
    • 特殊文字の制限は、引用符の間に含まれる場合にのみ使用する必要があることと、それらの2つ(バックスラッシュ\および引用符 "(ASCII:92、34))の前にバックスラッシュ\"\\"およびand "\"") 。
  • ローカル部分の両端に括弧を付けてコメントを入力できます。たとえばjohn.smith(comment)@example.com(comment)john.smith@example.comは、どちらもと同等ですが"john.smith@example.com"john.(comment)smith@example.com無効になります。
  • U+007FUTF-8としてエンコードされた上記の国際文字は、RFC 6531で許可されていますが、メールシステムはローカルパーツを割り当てるときに使用する文字を制限する場合があります。

グローバル/ドメイン部分の場合:

電子メールアドレスのドメイン名部分は、厳密なガイドラインに準拠する必要があります。文字、数字、ハイフン、およびドットで構成されるホスト名の要件に一致する必要があります。また、ドメイン部分はjsmith@[192.168.2.1]jsmith@[IPv6:2001:db8::1][…] などの角括弧で囲まれたIPアドレスリテラルでもかまいません。

出典:ウィキペディア

有効なものは何ですか?

これは奇妙な、しかし次のような有効な電子メールアドレスにつながる可能性があります。

  • localpart.ending.with.dot.@example.com
  • (comment)localpart@example.com
  • "this is v@lid!"@example.com
  • "much.more unusual"@example.com
  • postbox@com
  • admin@mailserver1
  • "()<>[]:,;\\@\"\\\\!#$%&\'*+-/=?^_`{}| ~.a"@example.org
  • " "@example.org

ソース:php.net / author gt@kani.hu –この投稿の著者によって修正された例

制限

ローカルおよびドメインの長さの制限もあります。

電子メールアドレスの形式はlocal-part@domainローカル部分の最大長は64文字ドメイン名の最大長は253文字です。ただし、最大256文字の順方向または逆方向パスでは、電子メールアドレス全体が制限されます。しないせいぜい254の文字 [2]の正式な定義は、RFC 5322である(セクション3.2.3と3.4.1)とRFC 5321 -情報RFC 3696 [3]および関連する正誤表で与えられるより読みやすい形式と。

出典:ウィキペディア

WordPressの制限

そして、これはWordPressがチェックするものです:

  • メールの最小長をテストします。 strlen( $email ) < 3
  • 最初の位置の後の@文字をテストします。 strpos( $email, '@', 1 ) === false
  • 無効な文字をテストします。 !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
  • 期間のシーケンスをテストします。 preg_match( '/\.{2,}/', $domain )
  • 先頭および末尾のピリオドと空白をテストします。 trim( $domain, " \t\n\r\0\x0B." ) !== $domain
  • :ドメインは、少なくとも二つの潜水艦を持つことになりますと仮定し$subs = explode( '.', $domain );、その後と
    • 2 > count( $subs )
    • trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
    • !preg_match('/^[a-z0-9-]+$/i', $sub )

ソース:WP Core v4.0

フィルターとカスタム検証

上記のすべてのケースは、is_email()falseを返すようにトリガーされます。結果はフィルター可能です(コールバックを添付できます)。フィルターには3つの引数があり、最後の引数が理由です。例:

return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );

つまり、特定のチェックによって返された結果をオーバーライドできます。

これにより、たとえばUmlautドメイン、TLDのみのドメインパーツなどを許可するための特別なチェックを追加できます。

結論

WordPressはほとんどの場合安全ですが、メールサーバーは実際にRFCに準拠する必要があるため、より制限が厳しくなります。すべてのメールサーバーがRF 6531ガイドラインに適合するわけではないことに注意してください。

編集

面白い副次的事実:内部には2つの関連する関数があります~/wp-includes/formattingis_email()sanitize_email()。これらは実質的に同じ機能です。他の人が提供するフィルターへのコールバックとして関数の内容を追加するのではなく、誰かが別の関数の内容をコピーすることをお勧めする理由を誰かが決めた理由はわかりません。以下のようv0.71以降およびV1.5以降は同じですあなたがきれいに文字列を取得して、私は個人的に後で使用します。RFCに準拠していないとさえ述べていることに注意してください。is_email() sanitize_email() is_email()


あなたは理論的にはRFC 6531に従って完全に有効な電子メールアドレスがそこにあると言っていますが、これらはWordPressによって無効とみなされますか?
ヘンリーライト14年

いくつかはい。たとえば、TLDのみのドメイン、ウムラウトドメインなど、最後の段落で回答の結論の前に読むことができます。答えをもう一度読んでください。頭を包むのは大変ですが、それだけの価値はあります。
カイザー14年

1
これは理解する価値のあるものなので、実際に2回読んでいます!このような詳細な回答をありがとう:)
henrywright 14年

2

すべてのものを消毒してください!

セキュリティの基本的なルールの1つは、ユーザーからの入力を決して信頼しないことです。一般に、is_email()または他の特定の関数の実装については気にしません。または、その関数が私が与えるもので何か危険なことをするかどうかは気にしません。実装はいつか変わるかもしれません。知るか。侵害される可能性があると思います。常にユーザー入力は積極的に敵対的であり、最終的にはデータベースを宛先とするものに対しては二重になり、何らかの機能に引き渡す前にユーザー入力のすべてのビットをサニタイズすることを前提とする必要あります。これはちょうど良い、一般的なセキュリティ衛生です。


実装が変更されるかどうかわからないと言ったとき、頭に釘を打ったと思います。今すぐサニタイズしないことは問題ないかもしれませんが、それが後日変更されるかどうかは誰にわかりますか?
ヘンリーライト14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.