문제

SQL Server 2005 및 Windows Server 2000으로 작업하고 있으며 코드를 강화하는 동안 SQL 주입 공격을 차단하는 '자동화 된'방법이 있는지 궁금합니다.

일부는 다음과 같은 방법이 있다고 제안했습니다.

  1. 주입 지향 기호에 대한 게시물 및 쿼리 스트링을 필터링하는 일종의 ISAPI 또는 HTTP 모듈을 넣고 응용 프로그램에 도달하기 전에 요청을 실패하십시오. 이러한 솔루션의 대부분은 IIS 6 이상입니다. 나는 5를 달리고있다.
  2. 각 명령 객체는 한 번에 단일 SQL 명령 만 실행하도록 보장합니다.

내 구성에 대한 다른 아이디어가 있습니까?

도움이 되었습니까?

해결책

서버에서 많은 주사 공격 시도를했을 때 불필요한 자원을 차지하고 있다고 걱정했습니다. 나는 대부분의 XSS 및 SQL 주입 공격을 걸러내는 C#에 HTTPModule을 썼다 (Hacked!). 코드는 웹 사이트를 사용하는 데 필요한 구성 섹션과 함께 아래에 붙여져 있습니다. 프로젝트에 넣고 WebSecurityFilter.dll로 편집되어 웹 프로젝트에 의해 참조되어야합니다 (또는 그렇지 않으면 빈 디렉토리에 삭제).

이것은 ASP.NET에서만 작동하므로 귀하의 사이트가 ASP.NET 기반이기를 바랍니다 (의견으로는 질문을 받았지만 답이 없었습니다).

웹 구성 섹션 (에 추가u003ChttpModules> 섹션u003Csystem.web> :

  <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
    }
}

잘만되면 모든 것이 형식화되었습니다 ...

오늘 저녁에 완전한 프로젝트에 대한 링크를 게시하려고 노력할 것입니다.

다른 팁

일반적으로 SQL 주입로부터 보호하기위한 자동 솔루션은 없습니다. SQL 주입은 데이터베이스 결함이 아닌 응용 프로그램 결함입니다.

솔루션은 응용 프로그램 데이터를 쿼리에 보간하는 SQL을 실행하는 모든 사례에 대한 코드 검토를 수행하는 것입니다.

이 제안 된 솔루션 :

각 명령 객체는 한 번에 단일 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'"

코드에서 취약성을 제거하는 데 집중하십시오.

모든 데이터베이스 통화가 저장된 절차 또는 매개 변수화 된 쿼리를 사용하는지 확인하십시오.

항상 사용자 입력을 소독합니다

  1. 당신이 '당신은 즉시 코드를 더 안전하게 만드는 데 어떤 길을 갈 것입니다.
  2. 쿼리가 정수가 예상되는 경우 입력이 정수인지 확인하십시오. 등
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top