Soluciones basadas en HTTP o SQL Server para inyección sql

votos
1

Estoy trabajando con SQL Server 2005 y Windows Server 2000 y me pregunto si hay alguna forma 'automatizada' de bloquear ataques de inyección SQL mientras aplico mi código.

Algunos han sugerido que hay formas de:

  1. Coloque algún tipo de módulo ISAPI o HTTP que filtre la solicitud de publicación y las cadenas de consulta para los símbolos orientados a la inyección y falla la solicitud incluso antes de que llegue a la aplicación. La mayoría de estas soluciones son específicas de IIS 6 o superior. Estoy corriendo 5.
  2. Garantice que cada objeto de comando ejecute solo un comando SQL a la vez.

¿Alguna otra idea para mi configuración?

Publicado el 09/12/2008 a las 21:41
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
1

Siempre desinfecte la entrada del usuario

  1. si no lo permites, irás de inmediato a hacer que tu código sea más seguro
  2. si su consulta espera un entero, asegúrese de que la entrada sea un número entero. etc
Respondida el 07/03/2009 a las 13:27
fuente por usuario

votos
1

Cuando tuve un montón de intentos de ataque de inyección en mi servidor, me preocupaba que estuvieran tomando recursos innecesarios. Escribí (¡pirateé!) Un HttpModule en c # que filtraría la mayoría de los ataques de inyección xss y sql. El código se pega a continuación, junto con la sección de configuración necesaria para que un sitio web lo use. Debe colocarse en un proyecto y compilarse en WebSecurityFilter.dll, que luego debe ser referenciado por el proyecto web (o, de lo contrario, descartado en el directorio bin).

Esto solo funcionará con asp.net, así que espero que su sitio esté basado en asp.net (lo hice en un comentario, pero no obtuve respuesta).

Sección de configuración web (agréguela en la sección <httpModules> de <system.web>:

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

Código para el módulo (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
    }
}

Espero que todo haya sido formateado bien ...

Trataré de publicar un enlace al proyecto completo en un zip esta noche.

Respondida el 09/12/2008 a las 22:34
fuente por usuario

votos
1

Asegúrese de que todas las llamadas a su base de datos utilicen procedimientos almacenados o consultas parametrizadas.

Respondida el 09/12/2008 a las 22:08
fuente por usuario

votos
1

Esta solución propuesta:

Garantice que cada objeto de comando ejecute solo un comando SQL a la vez.

en realidad no previene la inyección. Por ejemplo, un atacante puede inyectar una consulta de inicio de sesión para iniciar sesión sin credenciales. Considerar:

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

Esta plantilla se puede inyectar con una ID de usuario de:

' OR 1=1 --

Flexible:

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

Concentra tu esfuerzo en eliminar la vulnerabilidad del código.

Respondida el 09/12/2008 a las 21:56
fuente por usuario

votos
1

No hay una solución automática para proteger contra la inyección de SQL en general. La inyección SQL es una falla de la aplicación, no una falla de la base de datos.

La solución es que usted haga una revisión del código de todos los casos en los que ejecuta SQL que interpola los datos de la aplicación en la consulta.

Respondida el 09/12/2008 a las 21:49
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more