1

私は SQL Server 2005 と Windows Server 2000 を使用していますが、コードを補強している間に SQL インジェクション攻撃をブロックする「自動化された」方法があるかどうか疑問に思っています。

次の方法があると示唆する人もいます。

  1. ある種の ISAPI または HTTP モジュールを挿入して、リクエスト ポストとクエリ文字列をインジェクション指向のシンボルにフィルターし、アプリケーションに到達する前にリクエストを失敗させます。これらのソリューションのほとんどは、IIS 6 以降に固有のものです。5を実行しています。
  2. 各コマンド オブジェクトが一度に 1 つの SQL コマンドのみを実行することを保証します。

私の構成に関する他のアイデアはありますか?

4

5 に答える 5

1

サーバーで大量のインジェクション攻撃が試みられたとき、それらが不要なリソースを占有しているのではないかと心配しました。ほとんどの xss および sql インジェクション攻撃を除外する HttpModule を c# で (ハッキングして) 作成しました。コードは、Web サイトで使用するために必要な構成セクションと共に以下に貼り付けられます。これをプロジェクトに配置し、WebSecurityFilter.dll にコンパイルする必要があります。これは、Web プロジェクトによって参照される (または bin ディレクトリにドロップされる) 必要があります。

これはasp.netでのみ機能するため、サイトがasp.netベースであることを願っています(コメントで質問しましたが、回答がありませんでした)。

Web 構成セクション (<system.web> の <httpModules> セクションに追加します。

  <add name="SecurityHttpModule" type="WebSecurityFilter.SecurityHttpModule, WebSecurityFilter" />

モジュールのコード (SecurityHttpModule.cs):

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;

namespace WebSecurityFilter
{
    class SecurityHttpModule : IHttpModule
    {
        class RegexWithDesc : Regex
        {
            string _errorText;

            public string ErrorText
            {
                get { return _errorText; }
            }

            public RegexWithDesc(string regex, RegexOptions options, string errorText)
                :base(regex, options)
            {
                _errorText = errorText;
            }
        }
        /// <summary>
        /// error text displayed when security violation is detected
        /// </summary>
        private string _errorhtml =
        @"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN"" ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"">" +
        @"<html xmlns=""http://www.w3.org/1999/xhtml"" >" +
        @"<body style=""background:black;"">" +
        @"<table style=""width:100%"" >" +
        @"<tr><td align=""center"">" +
        @"<div style=""border:3px solid red;text-align:center;width:95%;color:red;padding:10px;text-decoration:blink;"">" +
        @"SECURITY VIOLATION" +
        @"<br/>" +
        //@"<br/>" +
        //@"go away" +
        //@"<br/>" +
        @"<br/>" +
        @"{0}" +
        @"<br/>" +
        @"</div>" +
        @"</td></tr>" +
        @"</table>" +
        @"</body>" +
        @"</html>";

        // regex for default checks
        // http://www.securityfocus.com/infocus/1768
        static RegexOptions _defaultRegexOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace;

        RegexWithDesc[] _regexCollection = new RegexWithDesc[] 
        { 
            new RegexWithDesc(@"((¼|<)[^\n]+(>|¾)*)|javascript|unescape", _defaultRegexOptions, "XSS 1"), //3.3
            // new RegexWithDesc(@"(\')|(\-\-)", _defaultRegexOptions, "SQL 1"), //2.1
            new RegexWithDesc(@"(=)[^\n]*(\'|(\-\-)|(;))", _defaultRegexOptions, "SQL 2"),    //2.2
            //new RegexWithDesc(@"\w*(\')(or)", _defaultRegexOptions, "SQL 3"),  //2.3
            new RegexWithDesc(@"(\')\s*(or|union|insert|delete|drop|update|create|(declare\s+@\w+))", _defaultRegexOptions, "SQL 4"),   //2.4
            new RegexWithDesc(@"exec(((\s|\+)+(s|x)p\w+)|(\s@))", _defaultRegexOptions, "SQL 5")    //2.5
        };
        #region IHttpModule Members

        public void Dispose()
        {
           // nothing to do
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            try
            {
                List<string> toCheck = new List<string>();
                foreach (string key in HttpContext.Current.ApplicationInstance.Request.QueryString.AllKeys)
                {
                    toCheck.Add(HttpContext.Current.ApplicationInstance.Request[key]);
                }
                foreach (string key in HttpContext.Current.ApplicationInstance.Request.Form.AllKeys)
                {
                    toCheck.Add(HttpContext.Current.ApplicationInstance.Request.Form[key]);
                }
                foreach (RegexWithDesc regex in _regexCollection)
                {
                    foreach (string param in toCheck)
                    {
                        string dp = HttpUtility.UrlDecode(param);
                        if (regex.IsMatch(dp))
                        {
                            HttpContext.Current.ApplicationInstance.Response.Write(string.Format(_errorhtml, regex.ErrorText));
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            return;
                        }
                    }
                }

            }
            catch (System.Threading.ThreadAbortException x)
            {
                throw;
            }
            catch (Exception ex)
            {
                HttpContext.Current.ApplicationInstance.Response.Write(string.Format(_errorhtml, "Attack Vector Detected"));
                HttpContext.Current.ApplicationInstance.Response.Write(string.Format(_errorhtml, ex.GetType().ToString()));
                HttpContext.Current.ApplicationInstance.CompleteRequest();
                return;
            }
        }

        #endregion
    }
}

うまくいけば、すべてが正常にフォーマットされます...

今晩、完全なプロジェクトへのリンクを zip で投稿しようと思います。

于 2008-12-09T21:34:20.793 に答える
1

一般に、SQL インジェクションから保護する自動ソリューションはありません。SQL インジェクションはアプリケーションの障害であり、データベースの障害ではありません。

解決策は、アプリケーション データをクエリに補間する SQL を実行するすべてのケースのコード レビューを行うことです。

于 2008-12-09T20:49:34.440 に答える
1

この提案されたソリューション:

各コマンド オブジェクトが一度に 1 つの SQL コマンドのみを実行することを保証します。

実際に注射を防止するものではありません。たとえば、攻撃者はログイン クエリを挿入して、資格情報なしでログインすることができます。検討:

"SELECT COUNT(*) FROM Users WHERE UserId = '{0}' AND PassHash = '{1}'"

このテンプレートには、次の UserId を挿入できます。

' OR 1=1 --

収量:

"SELECT COUNT(*) FROM Users WHERE UserId = '' OR 1=1 --' AND PassHash = 'sdfklahsdlg'"

コードから脆弱性を排除することに力を注いでください。

于 2008-12-09T20:56:00.637 に答える
1

すべてのデータベース呼び出しで、ストアド プロシージャまたはパラメーター化されたクエリのいずれかを使用していることを確認してください。

于 2008-12-09T21:08:46.587 に答える
1

ユーザー入力を常にサニタイズする

  1. ' 許可しない場合は、コードをより安全にするための何らかの方法がすぐに実行されます。
  2. クエリで整数が必要な場合は、入力が整数であることを確認してください。等
于 2009-03-07T12:27:47.390 に答える