ASP.NET MVC 5使用Filter過濾Action參數防止sql注入,讓你代碼安全簡潔


在開發程序的過程中,稍微不注意就會隱含有sql注入的危險。今天我就來說下,ASP.NET mvc 5使用Filter過濾Action參數防止sql注入,讓你代碼安全簡潔。不用每下地方對參數的值都進行檢查,看是用戶輸入的內容是否有危險的sql。如果每個地方都要加有幾個缺點:

1、工作量大

2、容易遺漏

3、不容易維護

下面我通過寫一個過濾防止sql的特性類,對Action執行前對Action的參數進行處理,如果有其值有sql語句,就會這些非法字符替換為空字符串。

一、sql注入的例子:

上面的輸入有兩個輸入框,用戶可以輸入任何的值,包括有sql注入的值。

后台代碼:

AdminController.cs

public class AdminController : Controller
    {
        public ActionResult Index(string name = "", string loginName = "", int page = 1)
        {
            ViewBag.Name = name;
            ViewBag.LoginName = loginName;
            var r = DAdmin.GetList(name, loginName, page, 2);
            return View(r);
        }
    }
}

DAdmin.cs:

public class DAdmin
{
    public static PageDataView<MSys_Admin> GetList(string name, string loginName, int page,int pageSize=10)
    {
        PageCriteria criteria = new PageCriteria();
        criteria.Condition = "1=1";
        if (!string.IsNullOrEmpty(name))
            criteria.Condition += string.Format(" and Name like '%{0}%'", name);
        if (!string.IsNullOrEmpty(loginName))
            criteria.Condition += string.Format(" and LoginName like '%{0}%'", loginName);
        criteria.CurrentPage = page;
        criteria.Fields = "*";
        criteria.PageSize = pageSize;
        criteria.TableName = "Sys_Admin a";
        criteria.PrimaryKey = "UID";
        var r = Common.GetPageData<MSys_Admin>(criteria);
        return r;
    }
}

上面對用戶輸入的name和loginName兩個參數沒有判斷是否有sql注入的非法字符,就直接拼接到sql語句,到數據庫中執行,這樣是非常危險的。

1、比如用戶在name輸入這樣的內容:

%'--%

這樣拼接出來的sql語句就成了

SELECT * FROM Sys_Admin WHERE Name like '%'--%'

這樣“--”是sql的注釋標記后面再拼接的sql語句都當成注釋了,這樣有效的就成了這樣的sql語句:

SELECT * FROM Sys_Admin WHERE Name like '%'

這表示顯示全部的記錄。如果是登錄的sql就會跳過用戶名、密碼的驗證。 

2、如果用戶name輸入內容帶有insert或delete或者drop,比如:

namer人值為:%';DELETE FROM Sys_Admin--%

拼接成的sql成了:

SELECT * FROM Sys_Admin WHERE Name like '%';DELETE FROM Sys_Admin--%'

這樣一執行就把Sys_Admin表的記錄全部刪除了。

總結:上面可以看到這種sql注入是多么的危險。

二、解決MVC sql注入方案

1、定義一個防止sql注入的字符串輔助類

{
    public static string FilterSql(string s)
    {
        if (string.IsNullOrEmpty(s)) return string.Empty;
        s = s.Trim().ToLower();
        s = ClearScript(s);
        s = s.Replace("=", "");
        s = s.Replace("'", "");
        s = s.Replace(";", "");
        s = s.Replace(" or ", "");
        s = s.Replace("select", "");
        s = s.Replace("update", "");
        s = s.Replace("insert", "");
        s = s.Replace("delete", "");
        s = s.Replace("declare", "");
        s = s.Replace("exec", "");
        s = s.Replace("drop", "");
        s = s.Replace("create", "");
        s = s.Replace("%", "");
        s = s.Replace("--", "");
        return s;
    }
}

這個類對上面sql相關的字符串都替換掉。

2、定義一個用來檢查並處理Action參數的特性類

public class AntiSqlInjectAttribute:FilterAttribute,IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        
    }
 
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var actionParameters = filterContext.ActionDescriptor.GetParameters();
        foreach (var p in actionParameters)
        {
            if (p.ParameterType == typeof(string))
            {
                if (filterContext.ActionParameters[p.ParameterName] != null)
                {
                    filterContext.ActionParameters[p.ParameterName] = StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
                }
            }
        }
    }
}

說明:這個特性類是繼承了類FilterAttribute和實現了接口IActionFilter,這里在方法OnActionExecuting處理Action的參數,OnActionExecuting是在Action執行之前運行的方法,而OnActionExecuted是在Action執行之后運行的方法。

p.ParameterType == typeof(string)

因為sql注入只有參數類型為字符串的時候才有可能所以這里只對Action參數為字符串的參數進行處理。

filterContext.ActionParameters[p.ParameterName] = 
StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
是用過濾之后的安全的Action參數值替換原來的原始值。

3、防止sql注入特性類的在MVC的Controller中的使用

public class AdminController : Controller
{
    [AntiSqlInject]
    public ActionResult Index(string name = "", string loginName = "", int page = 1)
    {
        ViewBag.Name = name;
        ViewBag.LoginName = loginName;
        var r = DAdmin.GetList(name, loginName, page, 2);
        return View(r);
    }
}

需要對Action的參數進行sql檢查,只用在前面加上,上面定義的特性類AntiSqlInject。這個特性類可以用在任何的需要防止sql注入的Action上,根本不用對手動的去過濾程序中獲取到的所有參數,安全、方便簡潔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM