web-dev-qa-db-ja.com

セキュリティ対策としてPHP(サーバー側))でユーザー入力の長さを検証する必要がありますか?

このユーザー入力は、正規表現(PHPのサーバー側で)を使用して検証およびサニタイズされ、データベースに挿入されることに注意してください。その後、同じWebサイト(たとえば、フォーラム)上の他のユーザーに表示されます。

ユーザーにどのくらいの長さを期待するべきかが事前にわかっている場合とそうでない場合の両方を指しますが、100文字以下であると想定できます。

ユーザー入力の長さをチェックすることでセキュリティ上の利点があるかどうかを把握しようとしています。

これは言語によって異なることを知っています。私はPHPを使用しています。 Java、.NET、Pythonなど)のような他の言語に関する情報で結構です。

14
rami300

一般的なルールとして、ユーザー入力をできるだけ制限する必要がありますが、それ以上は制限しないでください。町の名前を保持するために設計されたフィールドは、長さに制限はありません。しかし、名前をこれ以上長くすることはできないと考えて長さを25に制限すると、 ウェールズを混乱させる になります。

入力長が短いほど、たとえば、 SQLiまたはXSS。したがって、これらの攻撃に対する多層防御と見なすことができます。しかし、それがあなたの最初の防衛線である場合、あなたは深い問題に直面しています...

最後に、使用することにしたすべての制限はサーバー側に適用する必要があり、クライアントのみに適用する必要はないことは正しいです。

26
Anders

それはあなたが何を保護したいかによります。

入力の検証に使用される正規表現があるとのことですが、それは良いことですが、最終的には正規表現がどのように形成されるかに依存します。 RegExが次のようになっている場合は、おそらく問題ありません。

{\"name\":\"(.+?)\",\ ?\"age\":(\d+?)}

一方、RegExが次のようになっている場合...

({.+})

正規表現を使用すると言っても、SQLインジェクションやクロスサイトスクリプティングなどのさまざまな攻撃に対するそれらの安全性についての主張を行うには不十分です。

長さ検証doesから保護するのは、サービス拒否攻撃のいくつかの形式です。たとえば、HTTP POSTリクエストのサイズは数メガバイトになる場合があります。受信したものをデータベースにコピーするだけの場合、攻撃者はデータベースをゴミですぐにいっぱいにして、可用性に影響を与える可能性があります。

9
MechMK1

Webアプリのクライアント側での検証は簡単に回避できるため、セキュリティの観点から信頼すべきではありません。

ブラウザ開発者ツールには、クライアント側のコードを段階的に実行し、セキュリティチェックと検証をバイパスするように属性とスクリプトを変更できる、非常に優れたHTML/JavaScriptデバッガが含まれています。

平凡なハッカーでさえ、それを悪用する方法を知っています。セキュリティの観点から、サーバー側で検証を再確認する必要があります。

私のアプリでは、ほとんどのフロントエンドをサーバー側で実行しています。検証メッセージまたは確認ページのURLを返すIFRAMEまたはXmlHttpClientを使用して、ほとんどのフォームを送信します。これは開発がはるかに簡単で、ほとんどのフォームで非常に反応します。それでも、多くのクライアント側JavaScriptをコーディングしますが、それはパフォーマンスまたはユーザーエクスペリエンスにより大きな影響を与える場合に限られます。 80/20種類の戦略です。

1
Lucas

セキュリティ対策として?番号。

ユーザー入力による攻撃は、ユーザーが通常はデータベースクエリの形式で、適切にエスケープしていない変数にコマンドを入力できる場合に発生します。入力が切り捨てられた場合、不注意で攻撃が阻止される可能性がありますが、問題が実際に解決されるわけではありません。

セキュリティの観点から、すべてのユーザー入力を検証し、入力が保護された方法でのみ使用されていることを確認する必要があります。

  1. 値をHTMLで出力する場合は、HTMLタグが含まれていない(strip_tags)か、許可されているタグのみが含まれている(ライブラリを使用するか、DOMDocumentこの)。
  2. 値を計算で使用する場合は、有効な数値であることを確認してください。最も簡単な方法は、(int)$fooまたは(float)$fooとしてキャストすることですが、ニーズはさまざまです。
  3. 値をデータベースに保存する場合は、安全でない方法でクエリを作成しないようにしてください。クエリを安全に保つ最善の方法は、準備されたステートメントを使用することです。これにはPDOが適しています。それ以外の場合は、クエリを作成する前にユーザー入力をエスケープする必要があります。

値に文字と数字のみを入力するようユーザーに指示する場合、サーバーでは文字と数字のみを受け入れる必要があります。クライアント側に同じ条件を追加して、ユーザーへの驚きを防ぐ(フォームを送信する前にエラーを表示する)ことができますが、クライアント側の検証は有益であるため、サーバーは実際に自分を保護します(保護されていません(簡単にバイパスされます)。

その上で、フィールドに格納できる文字数が限られている場合、フィールドが長すぎる場合はユーザーに報告することもできます。

128文字以内の電子メールアドレスが必要だとすると、次のようにすべてのレベルでこれを処理できます。

データベース(モデル)

CREATE TABLE Emails `email` VARCHAR(128) NOT NULL

PHP(コントローラー)

$email = $_POST['email'];
if ((strlen($email) > 128) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // Produce error that input was invalid
    die('ERROR: Invalid e-mail');
}

// Input is valid, store in database (e.g- with PDO)
$stmt = $pdo->prepare('INSERT INTO Emails (email) VALUES (?)');
$stmt->execute([$email]);

HTML(表示)

<input name="email" type="email" maxlength="128" placeholder="E-mail" />

これにより、ストレージの効率性、正確性、安全性、ユーザーへのフィードバックをうまく組み合わせることができます。 HTML5をサポートするブラウザーを使用している場合、無効な値を送信しようとすると初期エラーが発生しますが、とにかくサーバーの安全性をチェックします(HTML5非対応ブラウザー、または悪意のあるユーザー)。

1
Haravikk

期待するユーザー入力を理解し、実際の入力が期待するものにできるだけ近いことを常に確認する必要があります。

予想よりも長いデータは、さまざまなタイプのセキュリティ問題を引き起こす可能性があります。

  • DOS攻撃/リソースの過剰使用:データベース内のダミー名に1 GBが浪費されている、または100文字を超えてはならない1GB名を正規表現で検証するためにCPUパワーが浪費されている
  • バッファ/データフィールド/整数オーバーフロー
  • ビジネスロジックの悪用:誰かが特定の長さの特定の入力を想定し、より長い長さのデータが悪用可能な方法でそれを壊すと想定するビジネスロジックを実装した

正規表現チェックは優れており、それ自体の長さチェックよりも厳密である可能性があります。暗黙的に長さチェックが含まれている場合、潜在的な問題の多くはすでにカバーされています。ただし、一部は残ります。たとえば、正規表現自体が攻撃される可能性があります。入力の検証に必要以上のCPUを使用するか、正規表現エンジンのバグをターゲットにします。正規表現も複雑であり、あなたや誰かが後でそれを変更して式を壊し、突然長さが正しくチェックされなくなる可能性が常にあります。明示的な軽量長さチェックはそれを防ぐことができます。それが価値があるかどうかは、常にどれくらい安全になりたいか、チェックを追加するのにどれだけの労力が必要か(維持するかなど)に依存します。

ユーザー入力が常に期待どおりのものに近いことを確認すると、常にセキュリティに影響がありますだけでなく、実装/メンテナンスの労力も増加します。人間は間違いを犯し、すべてのEdgeケースを考慮するわけではないため、Edgeケースが少ないほど、より実用的なセキュリティになります。具体的なシナリオでこのようなチェックが必要かどうかは、他にどのようなセキュリティ対策を講じているか、予想される攻撃シナリオは何か、何を警戒しているか、侵入の重要度などに常に依存します。

1
Frank Hopkins