web-dev-qa-db-ja.com

ウェブサイトのフィールドに入力できる文字を制限する必要がありますか?

今日、私は同僚と、アプリケーションが受け入れる必要のある文字について(やや白熱した)ディスカッションに入りました。これは、検索ボックスにanythingを入力でき、アプリケーションがその文字列による検索を忠実に実行するという発見によって促されました。ただし、これは検索ボックスだけでなく、アプリケーション内のすべてのテキストボックスにも同様に適用されます。

私の同僚は、(セキュリティの観点からの)ベストプラクティスは、許可された文字を一部の文字、数字、および記号のサブセットに制限することであるとの見方をしています。これにより、ユーザーがすべての種類の印刷不可能なUnicode制御文字とwhatnotelseを入力するのを防ぎます。

一方、これはユーザーを煩わせるだけで、追加のセキュリティは提供しないという意見です。ベストプラクティスは、アプリケーションにanythingを受け入れさせ、適切なエンコーディング関数(および利用可能な場合はパラメータ化されたクエリ)を使用して、入力した文字列が変更されずに通過し、入力したとおりに表示/使用されていることを確認してください。ユーザーがゴミを入力すると、ゴミが表示されますが、システムは正常に動作します。

ここでの業界のベストプラクティスは何ですか?

追加:よくわからないようです。問題はサーバー側に関するものであり、文字列を使用するときはすべての適切なエンコーディング/エスケープが適切であることが前提です(例:SQLのパラメーター、HTMLへの出力にHtmlEncodeを使用するなど)。それでも、クライアントから届く許可された文字を制限することは意味がありますか?

12
Vilx-

あなたのアプローチは-正しく使用されれば-SQLインジェクションとXSSの2つの非常に一般的な攻撃からあなたを守ります。そして、エスケープ/エンコード/準備されたステートメントは間違いなく必須であり、防御の主要なラインです。

ただし、検索ボックスについて具体的に言及しているように、このアプローチでは、たとえば、SQLワイルドカードDOS攻撃( here および here を参照)をキャッチできません。これは、入力検証(server-サイド;クライアントサイドJavaScriptでこれを行うべきではありません)。

あなたのアプローチはまたあなたのコードのセキュリティバグを捕らえません。コードベースが十分に大きくなると、適切なエンコードを1か所だけで忘れてしまう可能性が高まるため、サーバー側の入力検証という形で、それに対する追加の保護を行うことは悪い考えではありません。

また、ユーザーエクスペリエンスの観点からも問題はありません(ユーザーが無効なデータを入力した場合は、これをユーザーに報告して、問題点を認識し、有効なデータを入力できるようにすることをお勧めします)。

欠点は、それがより多くの仕事であることです。許可する必要がある入力と許可しない入力を実際に考える必要があります。既に述べたように、フィルターをかけすぎると、ユーザーが制限される可能性があるためです。可能な入力フィールドごとにこの作業を実行したくない場合は、Webアプリケーションファイアウォールが代わりになることがあります。

14
tim

クライアントを信用してはいけません。文字の入力を停止するJavascriptを記述しても、検索に文字を送信することはできます。

検索ルーチンは、サポートされていない文字を削除する必要があります。また、その文字を印刷するときは、送信された文字ではなく、実際に受け入れた文字を表示する必要があります。

フォームの汎用フィールドでは、より快適なユーザーエクスペリエンスのためにクライアント側の検証を追加することを検討してください。送信する前に、電話番号フィールドに数字以外の文字を入力しないことを知っておきたい。しかし、Javascriptのチェックを回避してフォームを送信すると、バックエンドサーバーは無効なデータを完全に拒否する必要があります。入力をサニタイズするためにJavascriptだけに任せないでください。

また、ほとんどのフィールドは、ユーザーが入力できるすべてのものを受け入れて他の場所で繰り返すことができますが、クロスサイトスクリプティングを防ぐために適切にエスケープする必要があります(たとえば、ユーザーが自分の名前を<script src="...">として設定できないようにするため) 。一部のフィールドには追加の懸念があります。たとえば、ユーザーが一意のユーザー名を選択できるようにした場合、 nicode Equivality を使用すると、別のユーザーの名前と同一に見える偽装を可能にする名前の一意のエンコーディングを選択できます。一部の文字は他の文字のように見えるため、正規化では不十分ですが、偽装は可能です。詳細については、 nicodeのセキュリティに関する考慮事項 を参照してください。

編集:あなたの同僚はまだポイントを持っています。サーバー側は孤立して存在しません。ユーザーからの入力を受け入れ、後でそれらの入力の一部を他のユーザーに表示する場合、サーバーサイドが危険な入力に対して完全に防護されているだけでは不十分です。クライアント側で発生するセキュリティの問題のカテゴリ全体があります。サーバー側に保存されているデータをそのまま正確にため、他のクライアント(攻撃されたり、それにだまされた)。 はい、サーバー側で入力文字を制限する必要があります。これは、ユーザーが再び引き渡されたときにユーザーを利用したり、だましたりする場合です。

推奨読書:

17
Stuart Caie

対策と理由の両方を実装する必要があります。

たとえば、ユーザーが入力できる文字スペース(a-zA-Z!@#$%^&*)を制限すると、知らないユーザーが台無しにしてジャンクデータを入力する可能性が低くなります。ただし、これは実際に、アプリケーションを使用しようとしているエンドユーザーが不正なデータを入力するのを防ぐだけです。 2番目のステップは、データの適切なサニテーションとエンコードを実行することで、XSS/SQLiやその他のさまざまな潜在的な攻撃から解放されます。

したがって、両方を使用してください。ユーザーエントリを制限して、よく知らないエンドユーザーを停止し、データをサニタイズして、もう少し賢いユーザーを停止します。

1
Ajaxasaur

上記の回答には良いアドバイスがたくさんありますが、質問の主要な部分、つまり入力データの数/サイズを制限することについて彼らが回答したかどうかはわかりません。

すでに述べられていることを要約する

  • クライアント側の入力検証とフィードバックを使用してクライアントのユーザーエクスペリエンスを向上させますが、セキュリティの目的でクライアント側に依存しないでください。すべてのクライアント側の対策は簡単に破られます。クライアント側はクライアント用であり、クライアントに焦点を当てる必要があります

  • サーバー側ですべてのセキュリティチェック、データの検証、データのサニタイズなどを行います。提供されたデータは敵対的で信頼できないと仮定します。ホイールを再発明するのではなく、十分にテストされた既知のソリューションを使用し、何かを許可しない場合はユーザーにフィードバックを提供して、何が起こっているのかを認識し、入力を再構成できるようにします

データの量と許可されるデータの制限に関する質問について、私が感じていることは、あなたが受け入れるものに対して寛大であり、あなたが行うことに対して保守的であるという概念の不正確な解釈です

  • 使用できないデータを受け付けても意味がありません。使用できるものは、アプリケーションを構成するコンポーネントの制限(データベース、サポートされる文字エンコーディング、最大バッファー制限など)によって異なります。

  • 長すぎるデータを受け入れて、どのような用途にも適合させることはできません。つまり、データベースのフィールド長より長いデータフィールドを受け入れても意味がありません。

  • 非常に長い入力データに関連するパフォーマンスヒットを検討してください。たとえば、検索文字列の場合、極端に長いクエリによって消費されるパフォーマンスまたはリソースがシステムに悪影響を及ぼしたり、使用できない結果を返すことになる制限はありますか?

  • 無制限の入力長さがバッファオーバーフローの脆弱性をトリガーするリスクはありますか?すべてのコンポーネント(ライブラリー、外部システム、データベースなど)は、任意の長さの入力データを処理できますか、それともクラッシュし、予期しない切り捨てなどを行いますか?

受け入れることに寛大であることは、受け入れるすべてを使わなければならないという意味ではありません。それは本当に失敗したりクラッシュしたりしないことを意味します。これは、入力を処理できない理由をユーザーにフィードバックし、エラーをキャッチして、適切に管理できるようにすることを意味します。提供されているものを使用できない場合や信頼できる方法で処理できない場合は、ユーザーエクスペリエンスを向上させるためにすべてを受け入れる必要があると主張しても意味がありません。ただし、理由や制限をユーザーに通知せずに、文字を静かにドロップしたり、入力を切り捨てたりしないでください。何が受け入れ可能で何が受け入れられないのかが明確でない場合にのみ、ユーザーは不満を感じます。期待があなたの能力と一致し、不満を感じるユーザーがはるかに少なくなるように、明確な情報を提供してください。

1
Tim X

純粋なセキュリティの観点からは、あなたのアプローチは正しいものです。 Webインターフェイス(html + javascript +何でも...)は、HTTPサーバーへの単なるクライアントです。言い換えれば、何でも/誰でもクライアントのセキュリティを通過することでリクエストを行うことができます。したがって、そのレベルのセキュリティは基本的にセキュリティではありません。

GUIの観点からは、実際にはjavascript/whateverで文字を制限することをお勧めします。例:フィールドに年齢があると想定されている場合、アルファベット文字を受け入れる理由はありません。あなたは少なくともユーザーからの構文上の問題を防ぎます。適切に設計されている場合、GUI(ユーザーへの迅速なフィードバック)とサーバー(検証エラーを返すリクエストを回避する)にとって大きなメリットになる可能性があります。

0
nsn