web-dev-qa-db-ja.com

有害なSQLインジェクションを許可するには短すぎるフィールド長はありますか?

私はSQLインジェクションについて読んでいて、これを見て、私は考えました:

入力フィールドをできるだけ小さくして、ハッカーが切り詰められることなくSQLコードをフィールドに押し込める可能性を減らします(通常、T-SQL構文エラーが発生します)。

ソース:Microsoft SQL Server 2008 R2 Unleashed

SQLインジェクションが害を及ぼす可能性のある最も短いフィールドサイズは何ですか?

データベースを変更したり、意図しない結果を返したりするのは危険です。終了コメントマーカー(--)2文字のフィールドでは害はありませんが、クエリが失敗するだけです。潜在的なハッカーは、フィールドがインジェクションの影響を受けやすいことを知っているかもしれませんが、それを活用することはできません。

51
James Jenkins

いいえ、短すぎて悪用できない長さはありません(少なくとも一部の状況では)。

長さフィルターはSQLインジェクションに対する有効な保護ではなく、準備されたステートメントは実際に唯一の適切な防御策です。

ただし、長さフィルターは、深層防御として適切な測定値です(整数フィルター、alphanumフィルターなど)。たとえば、有効な入力は30文字を超えることはありませんが、意味のある悪用にはさらに多くの文字が必要です。クライアント側は単純にバイパスできるため、多層防御はサーバー側で行う必要があることは言うまでもありません(ただし、おそらくそうではありません)。

制限バイパス

制限句(例:AND/OR)は2文字でバイパスできるため、クエリの失敗だけでなく、実際に害を及ぼす可能性があります。最も単純な例はログインです(他の例は、追加データの不正な削除です):

_SELECT * FROM users WHERE userid = [id] AND password = [password]
_

注入:

_id = 1#
password = wrong_password
_

ペイロード:2文字

DoS

DoS攻撃に必要な文字はごくわずかです。 MySQLの例では、実際の呼び出しに7、指定された秒にx、関数を呼び出してクエリを修正するために必要なものがすべてかかります。

例:

_SELECT * FROM users WHERE userid = [id]
_

インジェクション(これは有効なインジェクションです。長い形式は1 AND sleep(99)になります):

_sleep(99)
_

ペイロード:9文字

データの読み取り

データが表示される場合、長さは主にテーブルと列の名前に依存します。すべてのテーブルの列数が等しいと仮定します(発生する可能性があり、文字数が節約されます)。

例:

_SELECT * FROM comments WHERE commentid = [id]
_

注入:

_1 union select * from users
_

ペイロード:27文字。

データの編集

許可されていないデータベースの変更は、数文字でも実行できます。

例:

_UPDATE users SET password = '[password]' WHERE id = [id]
_

注入(パスワードへ):

_',isadmin='1
_

ペイロード:12文字

制限のバイパスも機能します(その結果、すべてのパスワードが空になります*)。

_'#
_

ペイロード:2文字

*パスワードの例は簡単にするために使用されています。パスワードはハッシュ化して、例を不可能にする必要があります。この例は、同様のすべての状況(ユーザー名の更新、権限の更新など)にも適用されます。

86
tim

コンテキストがなければ、作成者がクライアントアプリケーションの入力フィールドを参照していると想定します。使用する最も簡単な例は、WebアプリケーションのHTMLページのフォームですが、これから説明するのは、事実上すべてのタイプのクライアントアプリケーションに有効です。

ユーザーが最大入力フィールド長を制御していないであるため、SQL注入から保護するのに十分な短い最大入力フィールド長はありません。攻撃者はそうします。入力フィールドを含むフォームがクライアントに存在する場合(攻撃者のマシンのブラウザーウィンドウなど)、フォームは信頼境界の外にあり、制御できません。攻撃者が望むまたは必要とする任意の方法で操作したり、完全に回避したりできます。 Webアプリの場合、取得できるのはHTTPリクエストだけです。あなたはそれがどのように作成されたかを知りません、そしてあなたがブラウザに実行するように要求した何かが実際に起こったと信じる理由はありません、クライアント側のセキュリティ制御が実際に実行された、それはanythingリクエストのとおりですあなたが意図した、または何らかの方法で安全です。

したがって、いいえ、入力フィールドの長さは有効なSQLインジェクション防止メカニズムではなく、検証せずにセキュリティ境界を越える入力を信頼することは決してありません。

90
Xander

入力フィールドをできるだけ小さくして、ハッカーが切り詰められることなくSQLコードをフィールドに押し込める可能性を減らします(通常、T-SQL構文エラーが発生します)。

私見、これはただのたわごとです。入力フィールドの長さを使用してSQLインジェクションから保護するのはひどいアドバイスです。

  • SQLインジェクションから保護する唯一の正しい方法は、準備済みステートメントの使用です。入力データはクエリのパラメータであり、SQLテキストとして使用されることはありません。
  • フィールドのサイズを制御する必要がありますサーバー側リクエストの内容は信頼できないため、偽造されている可能性があるため、使用する必要があります。ビジネスレイヤーまたはデータベースストレージで使用する前にデータをサニタイズします。
  • ベストプラクティス以外のものを使用するためのアドバイスは、初心者の開発者を混乱させます。
11
Serge Ballesta

いいえ

クエリを考えてみましょう:

select * from tweets
WHERE RowNum >= [offset]
AND RowNum < [offset] + [limit]

offsetに整数以外の1つ(たとえば、文字 "a")を挿入できる場合、クエリは構文エラーになり、投稿が表示されないため、「意図しない結果」が生じます。損傷を引き起こすための要件。空の文字列を挿入できる場合は、長さがゼロのペイロードでも同じ効果が得られます。終了コメントを挿入すると、2文字の無駄になります;)

攻撃者はこれをサービス拒否攻撃に利用できます(通常、DoSに関連する ネットワークフラッディング とは異なりますが、- DoS とは異なります)。拒否されているサービスによっては、これは致命的な場合があります。

他の回答が示唆するように、フィールド長はSQLインジェクションの影響に影響を与えません。 OWASP SQLインジェクション防止のチートシート で説明されているように、準備され、パラメーター化されたステートメントを使用する方法です。

8
benrifkah

番号。

1文字のSQLインジェクションの簡単な例:

`

これは、「意図しない結果を返す」例となるエラーをスローします。多くの場合、エラーは、後で悪用に役立つ情報を取得するために使用できます。

4
MikeSchem

はい。

最大長はゼロです。他の検証やチェックを行わずに、信頼できない入力を最大長で安全にする唯一の方法は、インデックス0から始まる入力を完全に無視することです。

ここには他にも多くの(より良い)回答がありますが、これは、フィールド長が自由に使える唯一のツールである場合の安全性を保つ方法についての理論的な質問に答えるのに役立ちます。

3
Dan

このような攻撃は前のコードをコメント化して攻撃コードを開始するだけで機能するため、フィールドの長さはSQLインジェクションとは関係がないため、フィールドの長さはこの戦略に影響しません。

0

ここには多くの理論がありますが、実際の例はありません。実際のSQLインジェクションの脆弱性(現在はパッチが適用されている)を見つけたとき、約30文字の長さの入力フィールドを使用してみました。 30文字以降のすべてがドロップされ、30文字では余りスペースが取れないことを理解するのにしばらく時間がかかったので、これは非常にイライラしました。

(SQLインジェクションの多くの例には、「select * from table where id = @id」のような単純なsqlがあり、実際のSQLは通常、はるかに複雑になります)

入力を工夫することができ、SQLの専門家はおそらくいくつかのトリックを使用して、ペイロードの数を減らすことができます。しかし、いくら難しい場合でも、長いテーブル名を選択する場合は、そのために多くの文字が必要になります。

とにかく、1k文字以上の入力フィールドを使用するように切り替えたところ、SQLインジェクションには十分なことがわかりました。

そうは言っても、私の上の多くのコメンターが言ったように、SQLインジェクションに対する最善の防御策は準備されたステートメントです

0
Almenon