コードが古すぎてパラメーターを使用してms SQLサーバーと通信できないと主張するプロジェクトの1つで、where句に単純なブレークアウトが見つかりました。それはC++で書かれていて、私はこの言語を読むことができず、コードにアクセスすることができません。
問題を説明するために、無害なステートメントの例を追加しました。太字の部分は、ユーザーが直接入力できるものです
SELECT '1 ' SELECT 2- ';
このシナリオでは、1の後の単一引用符がブレイクアウトを引き起こしています。これは私がチームに示したものです。
次に、単一引用符を検索し、見つかった各単一引用符の後に3つの他の単一引用符を追加するコードで検出を行いました。したがって、例はこれになります
SELECT '1' '' 'SELECT 2-';
私はこのソリューションがまったく好きではありませんが、これ以上解決する方法を見つけることができません。データベース内のフィールドは、nvarchar文字として扱われて格納されます。何らかの種類のこの習慣を回避する可能性はまだありますか?
コードが古すぎて、パラメーターを使用してms SQLサーバーと通信できないと主張している
それはひどい言い訳です。 「あなたの車はとても古くて、シートベルトを組み込めない」と言っているようなものです。多くの作業をより近代的な手法でやり直す必要があるかもしれませんが、それは可能です。
彼らが適用した修正はエスケープであり、これは正しい解決策です(パラメーター化されたクエリの2番目に最適)。 MSSQLでアポストロフィ(または「単一引用符」)をエスケープするには、 プレフィックスに別のアポストロフィ を使用できます。開発者がなぜさらに2つ追加したのですか?私が考えることができる唯一の説明は、出力が再びSQLとして解釈されるということですが、正直なところ、私にはわかりません。
それから抜け出す方法については、あなたの質問のその部分はこれの複製のようです(あなたの質問はMSSQLに固有ですが):
答えは基本的に:
[...]さまざまなSQLデータベースを強制的にnicodeをローカル文字セットに変換することができる場合があります。たとえば、
Ā
はA
に変換できます。さらに悪いことに:U+02BC
、またはʼ
は'
、つまりU+0027
に変換されます。これはnicodeベースのスマグリングと呼ばれます。
彼らは危険な文字をエンコードしています-これは悪いアプローチではありませんが、他の問題を引き起こす可能性があります。彼らは文字列の長さを変更しています-エンコード後に長さをチェックすることに注意を払っていない場合は、バッファオーバーフローまで開放されるか、(場合によっては)途中でエンコードを切り捨てて、予期しない引用。
すべての単一引用符を入力して、何が起こるかを確認してください。
これが列名であると仮定して、一重引用符を拒否する方が適切であり、一重引用符を持つ列がないことを確認できます。