如何使用 ASP 过滤 XSS 攻击?可以通过在 ASP.NET 项目中配置请求拦截模块来实现,具体方法如下:
首先在 web.config 中添加 httpModules 节点,用于注册安全拦截模块,示例如下:
然后编写一个用于拦截和过滤 XSS 恶意请求的过滤器:
using System;using System.Collections.Generic;using System.Configuration;using System.Linq;using System.Text.RegularExpressions;using System.Web;namespace Org.Core.Commons{/// /// http访问拦截器模块/// 1.过滤危险关键词/// 2.增加安全Header/// public class HttpAccessInterceptModule : IHttpModule{private static List _RegexWords;static HttpAccessInterceptModule(){_RegexWords = new List(){@"<[^>]+>'", @"[^>]+>'",@"<[^>]+?style=[w]+?:expression(|b(alert|confirm|prompt|window|location|eval|console|debugger|new|Function|var|let)b|^+/v(8|9)|<[^>]*?=[^>]*?[^>]*?>|b(and|or)b.{1,6}?(=|>|<|binb|blikeb)|/*.+?*/| @"(^|(W+))" + o + @"((W+)|$)"));}public void Dispose(){}public void Init(HttpApplication context){context.BeginRequest += new EventHandler(Context_BeginRequest);context.EndRequest += new EventHandler(Context_EndRequest);}private void Context_BeginRequest(object sender, EventArgs e){HttpApplication app = (HttpApplication) sender;try{if (IgnoreRequest(app.Request.CurrentExecutionFilePath))return;RequestFiller(app.Request);AddHeader(app.Response);}catch (Exception ex){if (!(ex is PSBaseException))PSLog4net.Error(this, ex);app.Response.Write(ex.Message);app.Response.Flush();app.Response.End();}}private void Context_EndRequest(object sender, EventArgs e){HttpApplication app = (HttpApplication) sender;SetContentType(app);}private void RequestFiller(HttpRequest request){string error = "";if (request.Path.IndexOf("/log/", StringComparison.CurrentCultureIgnoreCase) >= 0)error = "不允许访问/log/目录";if (string.IsNullOrEmpty(error) &&request.Path.IndexOf("/bak/", StringComparison.CurrentCultureIgnoreCase) >= 0)error = "不允许访问/bak/目录";if (string.IsNullOrEmpty(error)){foreach (string key in request.Params.AllKeys){if (key == "aspxerrorpath")continue;string value = request.Params[key];if (!string.IsNullOrEmpty(value) && (value.Contains("jquery.alert") || value.Contains("image")))continue;if (!string.IsNullOrEmpty(key)){//if (Regex.IsMatch(key, @"W+"))//{// error = string.Format("存在访问风险,参数[{0}={1}]无法通过“{2}”校验.", key, value, @"W+");// break;//}foreach (string regex in _RegexWords){if (Regex.IsMatch(key, regex, RegexOptions.IgnoreCase)){error = $"存在访问风险,参数[{key}={value}]无法通过“{regex}”校验.";break;}}}if (!string.IsNullOrEmpty(error))break;if (!string.IsNullOrEmpty(value)){foreach (string regex in _RegexWords){if (Regex.IsMatch(value, regex, RegexOptions.IgnoreCase)){error = $"存在访问风险,参数[{key}={value}]无法通过“{regex}”校验.";break;}}}if (!string.IsNullOrEmpty(error))break;}}if (!string.IsNullOrEmpty(error)){Log4net.Error(this, error);throw new PSBaseException("存在访问风险,请求无法通过系统校验规则.");}}private void AddHeader(HttpResponse response){}private void SetContentType(HttpApplication app){if (app.Request.Url.AbsolutePath.EndsWith(".png", StringComparison.CurrentCultureIgnoreCase))app.Response.ContentType = "image/png";if (string.IsNullOrEmpty(app.Response.ContentType))app.Response.ContentType = "text/plain; charset=utf-8";}private bool IgnoreRequest(string requestPath){if (requestPath.EndsWith(".assx", StringComparison.CurrentCultureIgnoreCase) ||requestPath.EndsWith(".sjs", StringComparison.CurrentCultureIgnoreCase) ||requestPath.EndsWith(".asmx", StringComparison.CurrentCultureIgnoreCase))return true;elsereturn false;}}} 