ログイン用のユーザーの携帯電話番号を受け入れるログインフォームがあります。
携帯電話番号が送信されたら、携帯電話番号を検証するためにJavaScriptを呼び出します。私のクライアント側の検証は、携帯電話番号が9、8、または7で始まるか、携帯電話番号の長さが10に等しいかなどのチェックで構成されています。
これらの種類の検証が完了したら、入力した携帯電話番号とパスワードが一致するかどうかをサーバー側で確認します(認証)。
私はJavaScriptでいくつかのチェックを行っているので、ソースを表示して、この種のチェックが存在することを知ることができます。そして、このコードをmodifyして、すべてのユーザーに反映させることができます。たとえば、携帯電話番号が9、8、または7で始まるかどうかをチェックするコードを変更し、9を1に置き換えることができます(たとえば)。したがって、9から始まる数値を入力すると失敗します。
これらの種類の攻撃を防ぐ方法は?明らかな方法は、これらのチェックをサーバー側に置くことですが、少なくとも10種類のチェックがあり、サーバー側のチェックに過負荷をかけたくありません。
JavaScriptで攻撃者がこれらの値を変更し、それをすべてのユーザーに反映させるにはどうすればよいですか?
[〜#〜] edit [〜#〜]:クライアント側のJavaScriptコードは次のようになります。
var checkMobileNumber = form.mobileNumber.value;
if (checkMobileNumber.charAt(0) != 9 && checkMobileNumber.charAt(0) != 8 && checkMobileNumber.charAt(0) != 7) {
//Throw some error
}
サーバー側で10のチェックを実行しても、サーバーに実際にストレスがかかることはありません。あなたが毎秒数千の要求のポイントにない限り、あなたは大丈夫でしょう。その時点で、おそらくクラスタリングなどを実装します。セキュリティは常に追加のサイクルの価値があります。クライアント側の検証だけでは十分ではありません。検証について考えるときは、「ブラウザ」がコンテンツを生成した可能性があるという事実に関係なく、RAW HTTPのフィルタリングについて考える必要があります。
クライアント側の検証がある場合でも、 中間者攻撃 があり、検証が行われた後に生のHTTPリクエストの内容を変更できます。クライアント側の検証は、エンドユーザーの利便性のためのものなので、送信せず、エラーメッセージが表示されて再送信する必要があります。サーバーで実行される処理にセキュリティを提供するために、ブラウザーベースのアプリケーションでクライアント側の検証を行うことは考えていません。
攻撃が検証を変更する方法については、多くのことに依存します。たとえば、ページの動的な値は何ですか?クエリ文字列(GETパラメータ)からフィルタリングせずにパラメータを取得しますか? XSSまたはCSRF攻撃につながる可能性があります。これらの値が変更され、アプリケーションがそれらを処理するためです。もちろん、適切なエスケープやその他の手法でこれから保護することができます。攻撃は、ページにコードを挿入できるユーザースクリプトまたはプロキシのタイプをロードした可能性もあります。
「reflected」を使用しているので、「reflected XSS」についてさらに詳しく読むとよいでしょう。これは、攻撃ベクトルの1種類にすぎません。から [〜#〜] owasp [〜#〜] :
反映された攻撃とは、エラーメッセージ、検索結果、またはリクエストの一部としてサーバーに送信された入力の一部またはすべてを含むその他の応答など、挿入されたコードがWebサーバーに反映される攻撃です。反映された攻撃は、電子メールメッセージや他のWebサーバーなどの別のルートを介して被害者に配信されます。ユーザーがだまされて悪意のあるリンクをクリックしたり、特別に細工されたフォームを送信したりすると、挿入されたコードは脆弱なWebサーバーに移動し、攻撃がユーザーのブラウザーに反映されます。 「信頼された」サーバーからのコードであるため、ブラウザはコードを実行します。
あなたはすでに何をすべきかを知っています、問題はあなたが検証するより多くのものがあることです。簡単な答えは、安全なものが必要な場合は、すべての検証をサーバー側で実行することです。クライアント側のことに対してこれまでに行ったことは何でも、ハッカーはそれらを見て、変更することができます。
(mitm攻撃を忘れないでください。クライアント側の検証は役に立ちません)
ユーザーがサーバーに送信する内容をまったく制御できません。基本的なセキュリティの概念は決してユーザーを信頼するものではなく、これはこのような場合に当てはまります。クライアント側の保護機能を使用して、偶発的な不正なリクエスト(人のタイプミス)を防止し、便宜上の理由から。これらのチェックを強化して「安全」にしようとすることには、根本的な欠陥があります。
サーバーにどの程度の負荷がかかるかに関係なく、すべてのセキュリティ検証がサーバー側で行われていることを確認してください。残念ながら、他に選択肢はありません。
サーバーに負荷をかけたくない場合は、「セキュリティ」が壊れています。あなたはクライアントサイドにあなたが望むどんなセキュリティを置いても構いません、精通したクライアントはいつでも彼/彼女が好きなものをあなたのサーバーに送ることができます。サーバーはクライアント入力を信頼してはなりません。サーバーが受け取るものは、クライアント側に置いたソフトウェアからのものであると想定してはいけません。これは名目上のケースであり、あなたが想像した唯一のケースかもしれませんが、知識のあるユーザーは自分の望むあらゆるコンテンツをサーバーに送信できます。クライアント側のソフトウェアを変更できる、バイパスできる…
サーバーの負荷は心配ありません。それ以外の場合は、より適切なハードウェアを購入する必要があります。また、サーバーの負荷を最小限に抑えることができます。
Vaadin のような素晴らしいWebアプリフレームワークを使用すると、検証を一度開発して、クライアントとサーバーの両方で検証を実行できます。したがって、次のような利点があります。
そして、あなたはより少ないことでより多くを節約することができます。電話番号に対するすべての制約は本当に良いアイデアですか? 1人のユーザーがあなたが考えていなかった国の電話番号を持っている場合はどうなりますか?人々が国境を越えて自分の携帯電話を持つことができることを知っていますか? 1人のユーザーが電話番号にスペースを入力するとどうなりますか?これらの場合、ユーザーエクスペリエンスが低下します。これらのケースを禁止する正当な理由はありますか?それとも、あなたの制約は単に善よりも害を及ぼす厄介なものになるでしょうか?