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