8

重複の可能性:
一重引用符をエスケープし、ユーザー入力を一重引用符で囲むことにより、SQL インジェクションから保護できますか?

位置パラメーターを使用してクエリを実行しない従来のアプリがあり、どこにでも SQL があります。ユーザー入力にはアポストロフィが含まれる可能性があるため、すべての文字列入力は手動でアポストロフィをエスケープする必要があると (ここで説明する前に) 決定されました。

これは、簡単に使用できるように C# に変換された、本質的な元のコード (私が作成したものではありません) です。

private string _Escape(string input)
{
    return input.Replace("'", "''");
}

private bool _IsValidLogin(string userName, string password)
{
    string sql =
        string.Format
        (
            @"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = '{1}'",
            _Escape(userName),
            _Escape(password)
        );
    // ...
}

これは何らかの方法で壊れる可能性があるようですが、ユーザー入力によってどのように悪用される可能性があるかについては途方に暮れています。ユーザー入力は に到達するまでフィルタリングされていないと仮定_IsValidLoginし、パスワードがプレーンテキストで保存されているように見えることを忘れてください。

それを完全に強化するための解決策は明らかです-位置パラメーターを使用します-しかし、このコードが安全でない理由/方法を経営陣に示すための弾薬が必要なので、修正するために時間/費用を割り当てることができます.

注:これは壊れている可能性があると想定していますが、実際にはそうではない可能性があります。私は SQL のスーパースターではありません。

注 2: この質問はデータベースにとらわれないと言いましたが、このコードを特定のエンジンで利用できる場合は、貢献を歓迎します。

4

2 に答える 2

3

バックスラッシュによって悪用される可能性があります。

password = foo\' OR 1=1 --

になります:

password = foo\'' OR 1=1 --

クエリ:

"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = 'foo\'' OR 1=1 --'"

--この例ではコメント マークです。

この解決策は、プログラムがアポストロフィのみをフィルター処理 (重複) することを前提としています。

于 2010-03-04T14:44:35.673 に答える
0

まあ、私はそれが脆弱である方法を見ることができません。それで、それが変更されるべきである別の理由を議論しましょう---それはかなり非効率的です。MSSQL(および他のほとんどのハイエンドSQLサーバー)では、クエリが解析され、実行プランが考案されてから、クエリとプランが保存されます。クエリのexactコピーが再度要求されると、保存された実行プランが使用されます。パラメーターはこれに影響を与えないため、パラメーターを使用すると、プランが再利用されます。あなたがテキストを埋め込むならば、それは決してそうしません。

于 2010-03-04T14:49:15.230 に答える