using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using DonvvTools.Log; namespace Test.Framework.Filters { /// <summary> /// 防止SXX攻击过滤器 /// </summary> public class SafeFilter : ActionFilterAttribute { private const string strRegex = @"<[^>]+?style=[\w]+?:expression\(|\b(alert|confirm|prompt)\b|^\+/v(8|9)|<[^>]*?=[^>]*?[^>]*?>|\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|<\s*img\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)"; private static bool _verify = true; public override void OnActionExecuting(ActionExecutingContext filterContext) { var request = HttpContext.Current.Request; if ((request.Cookies != null && !VerifyCookie()) || (request.HttpMethod.ToUpper() == "GET" && !VerifyGetData()) || (request.HttpMethod.ToUpper() == "POST" && !VerifyPostData()) || !VerifyReferrer()) filterContext.Result = new RedirectResult($"/Account/Login"); } public static bool VerifyPostData() { for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++) { _verify = CheckData(HttpContext.Current.Request.Form[i].ToString()); if (!_verify) break; } return _verify; } public static bool VerifyGetData() { for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++) { _verify = CheckData(HttpContext.Current.Request.QueryString[i].ToString()); if (!_verify) break; } return _verify; } public static bool VerifyCookie() { for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++) { _verify = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower()); if (!_verify) break; } return _verify; } public static bool VerifyReferrer() => CheckData(HttpContext.Current.Request.UrlReferrer.ToString()); public static bool CheckData(string inputData) { if (Regex.IsMatch(inputData, strRegex)) { Logger.Debug("链接中含恶意字符串", $"请求链接:{HttpContext.Current.Request.RawUrl}"); return false; } return true; } } }