HTML5の興味深い機能は<input pattern="" />
attribute です。これにより、ブラウザーは開発者が提供する正規表現に対して入力フィールドの値を検証できます。
その後、これはフィールドの ValidityState
にバインドされ、UXフィードバックを照会したり、無効な送信を防止したりできます。
サーバーは同じ前提条件検証(およびXSRF)を実装します。
これを前提として、このクライアント側の検証パターンは成熟しており適切です、または何らかの理由でフォーム全体をインターセプトし、送信する前に従来のフィールドごとの検証を行うことが望ましいそれ?
セキュリティの観点から、サーバー上のすべてを再検証する必要があります。 HTML5の機能がどれほど美しく高度になっても、これは常に当てはまります。あなたは単にクライアントを信頼することはできません。 HTML5ルールに従うかどうかはわかりません。それがブラウザかどうかさえわからない。
HTML5機能を使用している場合でも、送信する前に独自のJSクライアント側でフォーム全体を検証する必要がありますか?セキュリティの観点からは重要ではありません。クライアント側の検証はとにかくセキュリティ値がゼロです-上記を参照してください-したがって、セキュリティの観点からは、まったく気にしない方がよいでしょう。
クライアント側の検証は、純粋にユーザーエクスペリエンスに関するものです。独自のJS検証または組み込みのHTML5が最高のUXを生み出すかどうかは興味深い質問ですが、ここでは取り上げません。
与えられた答えは素晴らしいです。しかし、私はこれをいくつかのコード/スクリーンショットで説明したかった。
肝心な点は、エンドユーザーはクライアント側を操作(無効化/完全に削除/バイパスまたは変更)できるということです。したがって、「クライアント側の検証」は、セキュリティの観点からはまったく役に立ちません。サーバーサイドで常に検証する必要があります。
次のようなHTMLフォームがあるとします。
_<form method="post" action="index.php">
<input type="email" name="emailAddress" required>
<button type="submit">Submit form</button>
</form>
_
これは、必須フィールド(required
属性)であると言って、電子メールアドレス(_type="email"
_)を要求しています。
空のものやメールアドレスではないものを送信しようとすると、エラーになります。
なぜこれがセキュリティの観点から役に立たないのですか?ユーザーがしなければならないのはHTMLを操作することだけです。 Webページのコピーを保存して編集し、再度開くことで、これを行うことができます。または、ブラウザの開発者ツールを使用してマークアップを編集することもできます。 クライアント側のコードであり、管理下にあるため、これを行うことができます.
フォームのマークアップを次のように変更するとします。
_<form method="post" action="index.php">
<input type="text" name="emailAddress">
<button type="submit">Submit form</button>
</form>
_
ここで、emailAddress
フィールドはtext
タイプ(つまり、email
ではない)であり、必須フィールドではない(required
属性を削除)と言っています。
これをサーバーに送信できます。 「andy」というテキスト文字列は明らかに有効なメールアドレスではありません。しかし、サーバー側の検証がないため(まだ)、サーバーに投稿されます。PHPコードで_$_POST['emailAddress']
_を使用すると、 "andy"がデータ。
データなしでフォームを送信することもできます。その場合、アプリケーション(サーバー側の検証なし)では、変数_$_POST['emailAddress']
_に空の文字列が含まれます。
これは、エンドユーザーとしてのクライアント側のコードを操作できるためにのみ可能でした。
サーバー側の検証が安全なのはなぜですか?エンドユーザーはサーバー側のコードを操作できません(サーバーが危険にさらされていない限り、これは別の問題です)そして、平均的な人のためにHTMLを操作するほど簡単なものではありません)。
したがって、PHPでは、次のようなチェックを行うことができます。
_if (!filter_var($_POST['emailAddress'], FILTER_VALIDATE_EMAIL)) {
die('Invalid email address');
}
_
これは非友好的なエラー処理方法ですが、ユーザーが有効な電子メールアドレスの代わりに「andy」を送信すると、スクリプトの実行が停止します。したがって、アプリケーションは、電子メールアドレスが存在することを期待していた変数として「andy」を決して使用しません。エンドユーザーは上記のPHPコードを操作できないため、検証をバイパスできる可能性が低くなります。 。これはサーバー側の検証です。エンドユーザーが変更することはできないため、エンドユーザーは(簡単に)変更することはできません。
なぜクライアント側の検証に煩わされるのですか?クライアント側の検証は、「見栄えの良い」ユーザーインターフェイスの機能強化、またはエラーメッセージや無効化フォームなどに役立ちます。田畑。たとえば、ユーザーがメールアドレスを誤って入力した場合に備えて、最初のスクリーンショットにそのメッセージを表示することは、間違いなく優れたUI機能です。フォームは最初の一連の条件では送信されないため、サーバーに送信される不要なデータが削減されます。しかし最終的には、クライアント側で行われたことはエンドユーザーが変更できます。したがって、これは決して安全ではなく、セキュリティの実践に関しては、「クライアント側の検証」を決して考えるべきではありません。クライアント側の検証は、主にユーザーインターフェイスの拡張のみを目的としています。
クライアント側の検証は、クライアント側のアプリケーションにも役立ちます(サーバーに要求/投稿しない場合)。たとえば、上記のフォームがあり、JavaScriptやjqueryで読み取ることにより、ページの_<div>
_にemailAddress
の内容を表示したとします。ユーザーが<script>alert('hello!');</script>
などの何かを入力し、検証がなかった場合、JavaScriptがフィールドの値を_<div>
_に書き込もうとしたときにアラートが生成されます。この場合、サーバーには何もポストされません。すべてクライアント側で行われるため、このタイプのシナリオでは、クライアント側の検証が役立ちます。ただし、ユーザーが検証を無効にできるという同じ根拠が適用されます。上記のコードを実行した場合、ローカルマシンでのみ発生し、アプリケーションの他のユーザーには発生しないため、ここでの影響は小さくなります。例えば:
次のコードを使用します(検証なし)。
_<form method="post" action="#">
<input type="text" name="emailAddress" id="emailAddress" size="100">
<button type="submit">Submit form</button>
</form>
<div id="test"></div>
_
そして、jqueryはフォームの内容をtest
というIDで_<div>
_に書き込みます。
_$(document).ready(function() {
$("button").click(function(e) {
e.preventDefault();
$("#test").html($("#emailAddress").val());
});
});
_
Andersが述べたように、クライアント側の検証はアプリケーションのセキュリティには無関係ですが、UXの観点からは非常に重要です。
クライアント側の検証に重点が置かれているため、フォームへの入力中にユーザーにスムーズで簡単な時間を提供します。私が知っている最も良い例は、jQuery Masksプラグインで、ユーザーに視覚的なフィードバックを提供しながら、入力サイズとパターンを制限するために使用できます。これは、サーバー側で予期されるものとは異なるパターンでユーザーからデータを受信するなど、セキュリティ以外の欠陥に役立つ場合がありますが、攻撃者によって簡単に無視されます。
tl; dr-十分なクライアント側の検証などはありません。単にクライアントを信頼せず、サーバーで受信したすべてのものを処理してから処理します。
これまでのところ、どの回答も実際には言及していないので、これを追加しましょう。
HTMLのanythingがセキュリティにまったく関係がない理由は、攻撃者が(コンソールにリクエストを入力するか、プラグイン)。実際には、ブラウザー(c/f curl
、wget
または任意のプログラミング言語)を起動することすらありません。
これらに関連する部分は[〜#〜] http [〜#〜]リクエストです。 HTMLペイロードではありません。そして、TLS/SSLレイヤーを除いて、実際の人からのHTTPリクエストの内容を保護するものは何もありませんcreatingリクエスト。
したがって、すべてのセキュリティをサーバー側で行う必要があります。すべてのクライアント側のチェックは、より良いユーザーエクスペリエンス(往復をスキップ)のためにそこにあります。
HTML検証は、クライアント側からHTMLコードを変更する方法を知らない人にのみ適用されます。これらのHTML検証は、クライアント側から簡単に削除および操作できます。常にデータベースで適切な検証を行ってください。