パラメータが文字列でない場合、SQLクエリをパラメータ化しないことは安全ですか?


113

SQLインジェクションに関しては、stringパラメーターをパラメーター化する必要性を完全に理解しています。それは本の中で最も古いトリックの1つです。しかし、いつパラメーター化しないことが正当化できるのSqlCommandでしょうか?パラメータ化しないで「安全」と見なされるデータ型はありますか?

たとえば、私はSQLの専門家の近くにいるとは考えていませんが、SQLインジェクションに対して脆弱で、a boolまたはan を受け入れ、それをintクエリに直接連結する可能性があるとは考えられません。

私の仮定は正しいですか、それとも私のプログラムに大きなセキュリティの脆弱性を残す可能性がありますか?

明確にするために、この質問にはタグが付けられています これは強く型付けされた言語です。私が言うとき、「パラメータを、」のようなものだと思います public int Query(int id)


14
パラメーターを使用しない場合、キャッシュされたクエリプランのメリットは得られません。提供する入力の新しい組み合わせごとに個別のクエリプランを作成する必要があります。
スコットチェンバレン

5
@MatthewWhitedあなたはそれがより少ない時間がかかることをどのように知っていますか?この状況は、現在の開発者と以前の開発者による特定のプロジェクトのあらゆる場所で発生します。実際にセキュリティが向上する場合は、回答を投稿してください。明確にするために、明らかにパラメーター化する方が良いことに同意します。しかし、それは本当に私の質問ではありません。
johnnyRose 2015

7
パラメータ化されたクエリは、主にパフォーマンスと最適化に使用されます。SQLインジェクションの防止は副作用です。
Salman A

13
OPは有効な質問をしたと思います。彼は潜在的なリスクを修正することのコスト/利益を評価しようとしています。その方程式は、そのリスクの可能性によって変化します。リスクがゼロであれば、私もそれをしません。彼はあなたが彼の時間の価値があると思うかどうかの主観的な判断のためではなく、可能性についての技術的な質問を求められました。OPはその呼び出しを行うことができる唯一のものです。
Swears-a-lotロット、2015

10
私自身を説明すると、私はdbaです。私はベストプラクティスを評価し、尊重します。完璧な世界では、すべてのコードが完璧です。悲しいことに、私が働いている世界では、解決する時間よりも解決すべき問題が多くあります。つまり、優先順位付けです。IMO既に機能し、安全で、許容可能なレベルで実行されるコードの書き換えは、贅沢のように聞こえます。(私には余裕がないこと)
Swears-a-lotサー

回答:


101

技術的には安全だと思いますが、侵入するのはひどい習慣です。このようなクエリを本当に作成しますか?

var sqlCommand = new SqlCommand("SELECT * FROM People WHERE IsAlive = " + isAlive + 
" AND FirstName = @firstName");

sqlCommand.Parameters.AddWithValue("firstName", "Rob");

また、型が整数から文字列に変わる状況で脆弱になります(名前に関係なく、文字が含まれている可能性がある従業員番号を考えてください)。

そのintためstring、EmployeeNumberのタイプをからに変更しましたが、SQLクエリを更新するのを忘れていました。おっとっと。


24
AddWithValue すでに使用を中止できますか?blogs.msmvps.com/jcoehoorn/blog/2014/05/12/...
RemarkLima

5
@RemarkLima値をパラメーターにマップするコードを動的に生成するときの解決策は何ですか?ブログの投稿はそのシナリオに対処できません。はい、SQLタイプがわかっている場合はそれを設定するための1行ですが、わからない場合は問題があります(またはその情報でモデルに注釈を付ける必要があります)。
casperOne

1
その後AddWithValue、ステートメントの動的な構築の一部としてデータベースタイプのマッピングを行わない限り、行き詰まります。ターゲット列のリストがあり、ディクショナリの一部として、必要に応じて型を指定できると思います。それ以外の場合は、パフォーマンスの影響を受けます。結局のところ、私が知っているのは、ただの良い情報です。
RemarkLima

8
@RemarkLimaポイントは「AddWithValueもう使用をやめることはできますか?」本当にあなたがタイプを知っていれば、その後は使用を控えるべきです」でなければなりませんAddWithValue
casperOne

2
ねえ、メッセンジャーを撃たないで、私はそれを書きませんでした;-)要点は残っています、そして最初からあなたのデザインに組み込まれているなら、あなたがタイプを知らなければならない理由はありません。ベストプラクティスとすべてのジャズ:-)
RemarkLima

65

あなたは(Webサーバなど)を制御コンピュータ上で強く型付けされたプラットフォームを使用する場合は、あなただけでクエリーのコードインジェクションを防ぐことができboolDateTimeまたはint(およびその他の数値)の値。懸念事項は、SQLサーバーにすべてのクエリの再コンパイルを強制し、どのクエリがどのような頻度で実行されているかに関する適切な統計情報を取得できないことによって引き起こされるパフォーマンスの問題です(キャッシュ管理に悪影響を及ぼします)。

しかし、「コンピュータ上で制御する」部分は重要です。それ以外の場合、ユーザーは、システムが使用する動作を変更して、これらの値から文字列を生成し、任意のテキストを含めることができるためです。

長期的に考えるのも好きです。今日の古くて強く型付けされたコードベースが自動翻訳を介して新しいホットネスの動的言語に移植され、突然型チェックが失われたが、動的コードに対する適切な単体テストがまだない場合に何が起こるか?

実際、これらの値にクエリパラメータを使用しない理由はありません。これについては、これが正しい方法です。値が実際に定数の場合は、SQL文字列に値をハードコードしますが、それ以外の場合は、なぜパラメーターを使用しないのですか?難しいことではありません。

結局のところ、これ自体をバグとは呼びませんが、匂いと呼びます。それ自体は、バグだけでは不十分ですが、バグが近くにあるか、最終的にはバグになるという強い兆候です。良いコードは臭いを残すことを避け、どんな良い静的分析ツールもこれにフラグを立てます。

残念ながら、これは真に勝てる種類の議論ではないことを付け加えておきます。「正しい」だけでは不十分で、同僚のつま先を踏んでこの問題を自分で解決しても、チームのダイナミクスが向上することはありません。それは最終的にそれが助けるよりももっと傷つく可能性があります。この場合のより良いアプローチは、静的分析ツールの使用を促進することです。これにより、既存のコードを対象にして、戻って修正する取り組みに正当性と信頼性がもたらされます。


1
それをパラメーター化することは間違いなく難しいことではありません。私の質問は、同僚が整数値を連結した一連のクエリを作成したために発生し、それらすべてを調べて修正するのは私の時間の無駄ではないかと思っていました。
johnnyRose

2
「バグですか」という質問は、私の質問の要約です。
johnnyRose

7
それは「におい」です。それ自体はバグには不十分ですが、バグが近くにある可能性が高いことを示しています。良いコードはにおいをなくそうとします。優れた静的分析ツールであれば、間違いなくフラグが立てられます。
Joel Coehoorn、2015

1
「におい」という言葉が好きです。私は代わりに「幼虫」のようなものを使用しましたが、それはまだかなりのバグではありませんが、将来の更新では、それを潰すか燻蒸するまでバックエンドで食べるウジに追いつくことができます。確かに、実稼働環境でネクロティックコードが発生する可能性は望んでおらず、この場合のように、ある程度の精巧さで開発されていないものがあると、そのようなものが存在する可能性があります。
CSS

1
これは間違っています。DateTimeまたはを使用してSQLインジェクションを作成する方法の例については、私の回答を参照してくださいint
Kaspars Ozols

53

場合によっては、文字列値以外のパラメータ化されていない(連結された)変数を使用してSQLインジェクション攻撃を実行することが可能です-Jonによるこの記事を参照してください:http : //codeblog.jonskeet.uk/2014/08/08/the-bobbytables -culture /

ToString呼び出されたときに、一部のカスタムカルチャープロバイダーは、文字列以外のパラメーターをそのSQLをクエリに注入する文字列表現に変換できるということです。


14
これは質問に答える唯一の投稿だと思います。本質的には、「intsを使用して注入をどのように行うこともできるのですか?」
Arturo TorresSánchez15年

3
ただし、CultureInfoとにかくSQLインジェクションが必要になる理由を理解するのが難しいトラップに閉じ込められたブービーなどのカスタムコードをインジェクトする立場にある場合は、
マーティンスミス

プラス1、実際に質問に答える唯一の答え
ken2k

@MartinSmith:外部からCultureInfoを変更する1つの可能な方法を示す私の回答を参照してください。
user1027167 2015

そのようなコードをアプリケーションで記述できるのに、なぜSQLインジェクションが必要なのでしょうか。
Reza Aghaei

51

これは非文字列型であっても安全ではありません常にパラメーターを使用します。限目。

次のコード例を検討してください。

var utcNow = DateTime.UtcNow;
var sqlCommand = new SqlCommand("SELECT * FROM People WHERE created_on <= '" + utcNow + "'");

一見コードは安全に見えますが、Windowsの地域設定でいくつかの変更を行い、短い日付形式でインジェクションを追加すると、すべてが変更されます。

日時注入

結果のコマンドテキストは次のようになります。

SELECT * FROM People WHERE created_on <= '26.09.2015' OR '1'<>' 21:21:43'

intタイプについても同じことができます。ユーザーはカスタムの負の符号を定義でき、SQLインジェクションに簡単に変更できます。

現在のカルチャの代わりにインバリアントカルチャを使用する必要があると主張する人もいますが、私はこのような文字列の連結を何度も見たことがあります+


10
誰がサーバー設定を変更できますか?ユーザーがサーバーで実行できる場合、データを破壊するためにSQLインジェクションは必要ありません。
Reza Aghaei

5
これが最良の答えです。これは、OPがこれがバグ/セキュリティの欠陥であることを懸念していることを検証する1つの方法を示しています。たとえば、SQLで日付時刻を連結することはさておき、パフォーマンスと将来の保証は、匂い技術的な負担だけではありません。@RezaAghaei質問はサーバー側で言及されたことがないため、SQLExpressを備えたWindowsアプリである可能性があります。どちらの方法でも質問の基準にはなりません。誰もが言うことができますが、誰もが共有サーバーホスティングやY2Kバグについて言うことができるのと同じように、この優れた答えに反論するためにサーバー設定にアクセスできます。サーバーがロックされていることに同意します。これは前提条件ではありません。
Jeremy Thompson、

2
intタイプについてあなたが言っていることの例を提供できますか?
johnnyRose 2015

1
回答してから数週間になりますが、投稿を編集して、カスタムの負の符号を定義する方法の例を追加することはできますか?
johnnyRose 2015年

23

"SELECT * FROM Table1 WHERE Id =" + intVariable.ToString()


セキュリティ
大丈夫です。
攻撃者は、型指定されたint変数に何も注入できません。

パフォーマンスが
良くない。

パラメータを使用する方が良いので、クエリは一度コンパイルされ、次回の使用のためにキャッシュされます。次回、異なるパラメーター値を使用した場合でも、クエリはキャッシュされ、データベースサーバーでコンパイルする必要はありません。

コーディングスタイル
悪い習慣。

  • パラメータが読みやすくなりました
  • 多分それはあなたがパラメータなしでクエリに慣れるようにして、多分あなたは一度ミスをしてこのように文字列値を使用し、そしてあなたはおそらくあなたのデータに別れを告げるべきです。悪癖!


"SELECT * FROM Product WHERE Id =" + TextBox1.Text


それはあなたの質問ではありませんが、将来の読者のために役立つかもしれませんが:

セキュリティ
災害!フィールドが整数の
場合でもId、クエリはSQLインジェクションの影響を受ける可能性があります。アプリケーション"SELECT * FROM Table1 WHERE Id=" + TextBox1.Textにクエリがあるとします。攻撃者がテキストボックスに挿入する1; DELETE Table1と、クエリは次のようになります。

"SELECT * FROM Table1 WHERE Id=1; DELETE Table1"

ここでパラメーター化されたクエリを使用しない場合は、型指定された値を使用する必要があります。

string.Format("SELECT * FROM Table1 WHERE Id={0}", int.Parse(TextBox1.Text))


あなたの質問


私の質問は、同僚が整数値を連結した一連のクエリを作成したために発生し、それらすべてを調べて修正するのは私の時間の無駄ではないかと思っていました。

これらのコードの変更は時間の無駄ではないと思います。確かに着替えがオススメです!

同僚がint変数を使用している場合、セキュリティリスクはありませんが、これらのコードを変更しても時間の無駄ではなく、実際にこれらのコードを変更することをお勧めします。これにより、コードが読みやすくなり、保守が容易になり、実行が速くなります。


最初のオプションでさえ、セキュリティのために完全に大丈夫ではありません。の動作は.ToString()、任意のテキストを含めるように変更するのが簡単なオペレーティングシステム構成項目によって決定されます。
Joel Coehoorn

18

実際には2つの質問があります。そして、タイトルからの質問は、その後のコメントでOPによって表明された懸念とはほとんど関係がありません。

OPにとって重要なのは特定のケースであることは理解していますが、Googleからの読者にとっては、より一般的な質問に答えることが重要です。私が連結しているすべての文字は安全ですか?」なので、この後者に集中したいと思います。そして答えは

間違いなくNO。

説明はほとんどの読者が望むほど直接的ではありませんが、最善を尽くします。

私はしばらくの間この問題について考えていましたが、その結果(PHP環境に基づいていますが)記事にまとめて、すべてをまとめようとしました。SQLインジェクションからの保護の問題は、文字列のエスケープ、型のキャストなど、関連しているがより狭いトピックに対してはしばしば見逃されていることに気づきました。一部の対策は、単独で使用しても安全と見なすことができますが、従うべきシステムや単純なルールはありません。そのため、開発者の注意と経験に過度の負担がかかり、非常に滑りやすくなっています。

SQLインジェクションの問題は、いくつかの特定の構文問題の問題に単純化することはできません。かつて考えられていた平均的な開発者よりも幅が広いです。それは方法論的な問題でもあります。「どの特定のフォーマットを適用する必要があるだけでなく、「どのように行う必要があるか」も同様です。

(この観点から、他の回答で引用されたJon Skeetの記事は、特定の構文の問題に集中していて問題全体に対処できずに、いくつかのエッジケースで再び問題を引き起こしているため、良いというよりはむしろ悪いことをしています。)

保護の問題全体ではなく、一連の異なる構文問題として対処しようとすると、多くの問題に直面します。

  • 可能なフォーマットの選択肢のリストは非常に膨大です。簡単に見落とす可能性があることを意味します。または、それらを混同します(たとえば、識別子文字列エスケープを使用します)。
  • 連結とは、すべての保護手段をプログラムではなくプログラマが実行する必要があることを意味します。この問題だけで、いくつかの結果が生じます。
    • このようなフォーマットは手動です。手動は非常にエラーが発生しやすいことを意味します。申請を忘れる可能性があります。
    • さらに、フォーマット手順をいくつかの集中化された関数に移動し、さらに混乱させ、データベースに送らないデータを損なう誘惑があります。
  • 複数の開発者が関与する場合、問題は10倍になります。
  • 連結を使用すると、潜在的に危険なクエリを一目で見分けることはできません。それらはすべて潜在的に危険です!

その混乱とは異なり、準備されたステートメントは確かに聖杯です。

  • それは従うのが簡単な1つの単純なルールの形で表すことができます。
  • それは本質的に切り離すことのできない手段であり、開発者が干渉することはできず、喜んでまたは思わずにプロセスを台無しにすることを意味します。
  • インジェクションからの保護は、実際には準備されたステートメントの副次的な効果にすぎません。その真の目的は、構文的に正しいステートメントを生成することです。そして、構文的に正しいステートメントは100%インジェクションの証拠です。しかし、注入の可能性があっても、構文を正しくする必要があります。
  • ずっと使用すると、開発者の経験に関係なくアプリケーションを保護します。たとえば、2次注入と呼ばれるものがあります。そして、「保護するために、ユーザーが提供するすべての入力をエスケープする」という非常に強力な妄想 。これらを組み合わせると、開発者が自由に判断し、何を保護する必要があり、何をしないかを決定する場合、それらは注入につながります。

(さらに考えると、配列などの複雑なデータ構造と、SQLキーワードや識別子でさえ追加する必要がある場合があるため、現在のプレースホルダーのセットは実際のニーズに十分ではなく、拡張する必要があることを発見しました。動的にもクエリを実行しますが、開発者はそのような場合に準備ができておらず、文字列の連結に強制的にフォールバックしますが、それは別の問題です)。

興味深いことに、この質問の論争は、スタックオーバーフローの非常に物議を醸している性質によって引き起こされています。このサイトのアイデアは、直接尋ねるユーザーから特定の質問を利用して、検索から来たユーザーに適した汎用回答のデータベースを作成するという目標を達成することです。アイデア自体は悪くありませんが、次のような状況では失敗します。ユーザーが非常に狭い質問をするとき、特に同僚との論争で議論を得るとき(またはコードをリファクタリングする価値があるかどうかを決定するとき)。経験豊富な参加者のほとんどが回答を書き込もうとしていますが、、使命て全体的にスタックオーバーフローを念頭に置き、OPだけでなく、できるだけ多くの読者に回答を提供します。


10
質問に答えない
edc65

ほとんどのデータベースは、SQL文字列の等価性によって既に使用され、パラメータ化されたクエリを検出するため、古いprepare-and-use-handleメソッドは時代遅れのようです。これらのハンドルは特定のスコープ内でのみ使用でき、ハンドルを追跡するためのコーディングが必要です。私の意見では、パラメーター化されたクエリは直接使用する必要があります。これにより、クエリプランを、ハンドルトラッキングなしで、さらには異なるアプリケーション間で再利用できます。
Erik Hart、

15

セキュリティやタイプセーフの考慮事項だけを考えてみましょう。

パラメータ化されたクエリを使用する理由は、データベースレベルでパフォーマンスを向上させるためです。データベースの観点からは、パラメーター化されたクエリはSQLバッファー内の1つのクエリです(Oracleの用語を使用するには、内部的にはすべてのデータベースに同様の概念があると思います)。したがって、データベースは一定量のクエリをメモリに保持し、準備して実行する準備ができています。これらのクエリは解析する必要がなく、より高速になります。頻繁に実行されるクエリは通常バッファ内にあり、使用されるたびに解析する必要はありません。

なし

誰かがパラメータ化されたクエリを使用していません。この場合、バッファはほぼ同一のクエリのストリームによって継続的にフラッシュされ、それぞれがデータベースエンジンによって解析および実行される必要があり、頻繁に実行されるクエリでも何度も再解析されるため、パフォーマンスはオールラウンドに低下します。日。私はデータベースを生計用に調整しましたが、これは簡単に実を結ぶ最大の情報源の1つです。

質問に答えるために、クエリに少数の個別の数値がある場合、おそらく問題は発生せず、実際にパフォーマンスが無限に向上する可能性があります。ただし、値が数百にもなる可能性があり、クエリが頻繁に呼び出される場合は、システムのパフォーマンスに影響を与えるため、実行しないでください。

はい、SQLバッファーを増やすことはできますが、最終的には常に、インデックスやデータのキャッシュなど、他のより重要なメモリの使用が犠牲になります。道徳的に、パラメーター化されたクエリをかなり忠実に使用して、データベースを最適化し、重要なもののためにより多くのサーバーメモリを使用することができます...


8

Maciek回答に情報を追加するには:

リフレクションによってアセンブリのmain関数を呼び出すことにより、.NETサードパーティアプリのカルチャ情報を簡単に変更できます。

using System;
using System.Globalization;
using System.Reflection;
using System.Threading;

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      Assembly asm = Assembly.LoadFile(@"C:\BobbysApp.exe");
      MethodInfo mi = asm.GetType("Test").GetMethod("Main");
      mi.Invoke(null, null);
      Console.ReadLine();
    }

    static Program()
    {
      InstallBobbyTablesCulture();
    }

    static void InstallBobbyTablesCulture()
    {
      CultureInfo bobby = (CultureInfo)CultureInfo.InvariantCulture.Clone();
      bobby.DateTimeFormat.ShortDatePattern = @"yyyy-MM-dd'' OR ' '=''";
      bobby.DateTimeFormat.LongTimePattern = "";
      bobby.NumberFormat.NegativeSign = "1 OR 1=1 OR 1=";
      Thread.CurrentThread.CurrentCulture = bobby;
    }
  }
}

これは、BobbysAppのMain関数がパブリックである場合にのみ機能します。Mainがパブリックではない場合、呼び出す他のパブリック関数がある可能性があります。


1
コードでそれを行う必要すらありません。Windowsの地域設定で直接注入を追加できます。私の答えを見てください。
Kaspars Ozols

2
誰がサーバー設定を変更できるのか、そのようなコードをサーバーでこするのは誰ですか?ユーザーがサーバーで実行できる場合、データを破壊するためにSQLインジェクションは必要ありません。
Reza Aghaei

7

私の意見では、使用するパラメーターに文字列が含まれないことを保証できる場合、それは安全ですが、どのような場合でもそれは行いません。また、連結を実行しているため、パフォーマンスがわずかに低下します。私があなたに尋ねる質問は、なぜパラメータを使用したくないのですか?


1
パラメータを使いたくないということではなく、パラメータを使っています。同僚がこのようなコードを書いて、今日それをパラメーター化するように変更しました。
johnnyRose 2015

OK。すごい。パラメータを使用することがベストプラクティスです。この方法では、SQLインジェクションのようなことを心配する必要はありません。また、動的クエリを作成する場合は、クエリがどれほど複雑であっても、パラメータを使用できます。作成するときは、@ 1 ... @ nスタイルを使用するだけです。そして、それらを目的の値でパラメーターコレクションに追加します。
最大

@johnyRoseパラメータを使用するもう1つのポイントがあります。プログラムは進化し、変化しています。連結は文字列に対してのみ使用できますが、それは誰かが一部のパラメータタイプを変更するリファクタリングを実装し、その変更がSQLインジェクションの脆弱性をもたらす可能性があることを保証するものではありません。
lerthe61 2016

3

それは問題ありませんが、決して安全ではありません。セキュリティは常に入力に依存します。たとえば、入力オブジェクトがTextBoxの場合、テキストボックスは文字列を受け入れることができるため、攻撃者はトリッキーなことを行うことができ、何らかの検証/変換を行う必要があります。ユーザーの誤入力を防ぐことができます。しかし問題は、安全ではないということです。それと同じくらい簡単です。


それは文字列です。整数、ブール、日付時刻など、他のデータ型について話している。
johnnyRose 2015

@johnnyRose Yup、Kaspardsによって回答済みとしてマークされた上記の非常に素晴らしい例を見てきました。そして、彼がdatetimeデータ型を珍しい例として使用しているので、素晴らしい回答です。:)あらゆる種類のデータ型でパラメーターを使用することは安全ではなく、より良いことであるとすでに納得していると思います
japzdivino

パラメータを使用する方が安全であることに疑いはありませんでした。私の質問は強く型付けされた実装に言及しました。
johnnyRose 2015年

そうだね。そしてそれはまた、将来の読者を助けることができる素晴らしい質問です:)
japzdivino

-2

いいえ、SQLインジェクション攻撃をその方法で受けることはできません。私はトルコ語で古い記事を書いています。PHPとMySQLの記事の例ですが、概念はC#とSQL Serverで同じように機能します。

基本的には次のように攻撃します。整数のID値に従って情報を表示するページがあるとしましょう。以下のように、これを値でパラメーター化しません。

http://localhost/sqlEnjeksiyon//instructors.aspx?id=24

さて、あなたはMySQLを使用していると思います。私は次のように攻撃します。

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII((SELECT%20DATABASE()))

ここで注入された値は文字列ではないことに注意してください。ASCII関数を使用してchar値をintに変更しています。"CAST(YourVarcharCol AS INT)"を使用して、SQL Serverで同じことを実行できます。

その後、データベースの名前を見つけるために、長さと部分文字列関数を使用します。

http://localhost/sqlEnjeksiyon//instructors.aspx?id=LEN((SELECT%20DATABASE()))

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII(SUBSTR(SELECT%20DATABASE(),1,1))

次に、データベース名を使用して、データベース内のテーブル名の取得を開始します。

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII(SUBSTR((SELECT table_name FROM INFORMATION_SCHEMA.TABLES LIMIT 1),1,1))

もちろん、クエリごとに1文字しか取得できないため、このプロセスを自動化する必要があります。しかし、簡単に自動化できます。私の記事はwatirの 1つの例を示しています。パラメータ化されたID値ではなく、1ページのみを使用します。私はあなたのデータベースのすべてのテーブル名を知ることができます。その後、私は重要なテーブルを探すことができます。時間はかかりますが、実行可能です。


2
私の質問は強く型付けされた言語に言及しています。あなたの説明は柔軟なタイピングを持つ言語に最適ですが、注入された値は文字列のままです。
johnnyRose

注入された値は整数ではありません。charを取得し、ASCII MySQL関数を使用してそれを整数に変更します。SQL Serverでは、CAST(YourCharValue AS INT)を使用して同じことを行います
Atilla Ozgur

私はこのようなものを意味しました:public void QuerySomething(int id) { // this will only accept an integer }
johnnyRose

-3

ええと... 1つ確かなことは、SQLコマンド文字列と文字列(ユーザーが取得した文字列)を連結する場合、セキュリティには問題があるということです。where句がIntegerまたは任意の型を参照する場合は常に問題ではありません。注射が発生する可能性があります。

SQLインジェクションで重要なのは、ユーザーから値を取得するために使用された変数のデータ型です。

where句に整数があり、次のように仮定します。

  1. ユーザー変数は文字列です。その後、OK(UNIONを使用して)を注入することは非常に簡単ではありませんが、「OR 1 = 1」を使用してバイパスすることは非常に簡単です-攻撃のように...

  2. ユーザー変数が整数の場合。次に、システムのクラッシュや隠しバッファのオーバーフロー(最後の文字列)の異常なテストに合格することで、システムの強度を「テスト」できます...;)

クエリへのパラメーター、またはストアドプロシージャへのパラメーター(さらに優れた-imo)は100%脅威に対して安全ではありませんが、最小化するために最低限必要な手段(または必要に応じて基本的な手段)です。


あなたはその質問を誤解したかもしれません。文字列型について話しています。
johnnyRose

こんにちはJonnyRose ...ご連絡ありがとうございます。私はあなたの質問を理解しましたが、私は私の回答をより一般的な形にしています。文字列以外の場合は、私の(2)点を確認してください。;)
Andreas Venieris 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.