Magicodes.WeiChat——使用AntiXssAttribute阻止XSS(跨站脚本攻击)攻击

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。

很多时候,我们并不需要屏蔽所有的HTML标签,或者,我们需要设置某些属性支持的HTML标签字符串。还好,框架中封装了相关的特性,以便你直接拿来使用。

命名空间:Magicodes.WeiChat.Infrastructure.MvcExtension.Filters

类名:AntiXssAttribute

Demo:

[AntiXss]
              public string Name { get; set; }

              [AntiXss(allowedStrings: "<br />,<p>")]
              public string Description { get; set; }

              [AntiXss(allowedStrings: "<br />", disallowedStrings:"/, #")]
              public string NoSlashesOrHashes { get; set; }

              [AntiXss(errorMessage: "This is a custom error message")]
              public string CustomError { get; set; }

              [AntiXss(errorMessageResourceName:"TestMessage", errorMessageResourceType: typeof(TestResources))]
              public string ResourceCustomError { get; set; }

具体代码如下所示:

/// <summary>
    /// AntiXss验证特性,防止XSS攻击
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class AntiXssAttribute : ValidationAttribute
    {
        const string DefaultValidationMessageFormat = "字段 {0} XSS验证失败,请检查输入的字符串中是否含有非法字符。";
        private readonly string errorMessage;
        private readonly string errorMessageResourceName;
        private readonly Type errorMessageResourceType;
        private readonly string allowedStrings;
        private readonly string disallowedStrings;
        private readonly Dictionary<string, string> allowedStringsDictionary;

        /// <summary>
        /// 初始化 <see cref="AntiXssAttribute"/> 的新实例.
        /// </summary>
        /// <param name="errorMessage">错误消息</param>
        /// <param name="errorMessageResourceName">获取或设置错误消息资源的名称,在验证失败的情况下,要使用该名称来查找 ErrorMessageResourceType 属性值</param>
        /// <param name="errorMessageResourceType">获取或设置在验证失败的情况下用于查找错误消息的资源类型。</param>
        /// <param name="allowedStrings">以逗号分隔的允许的字符串。</param>
        /// <param name="disallowedStrings">以逗号分隔的字符串不允许的字符或单词</param>
        public AntiXssAttribute(
            string errorMessage = null,
            string errorMessageResourceName = null,
            Type errorMessageResourceType = null,
            string allowedStrings = null,
            string disallowedStrings = null)
        {
            this.errorMessage = errorMessage;
            this.errorMessageResourceName = errorMessageResourceName;
            this.errorMessageResourceType = errorMessageResourceType;
            this.allowedStrings = allowedStrings;
            this.disallowedStrings = disallowedStrings;
            allowedStringsDictionary = new Dictionary<string, string>();
        }
        /// <summary>
        /// 确定对象的指定值是否有效。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool IsValid(object value)
        {
            return true;
        }
        /// <summary>
        /// 确定对象的指定值是否有效。
        /// </summary>
        /// <param name="value"></param>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
            {
                return base.IsValid(null, validationContext);
            }

            var encodedValue = EncoderHelper.HtmlEncode(value.ToString(), false);

            if (EncodedStringAndValueAreDifferent(value, encodedValue))
            {
                SetupAllowedStringsDictionary();

                foreach (var allowedString in allowedStringsDictionary)
                {
                    encodedValue = encodedValue.Replace(allowedString.Value, allowedString.Key);
                }

                if (EncodedStringAndValueAreDifferent(value, encodedValue))
                {
                    return new ValidationResult(SetErrorMessage(validationContext));
                }
            }

            if (!string.IsNullOrWhiteSpace(disallowedStrings)
                && disallowedStrings.Split(‘,‘).Select(x => x.Trim()).Any(x => value.ToString().Contains(x)))
            {
                return new ValidationResult(SetErrorMessage(validationContext));
            }

            return base.IsValid(value, validationContext);
        }

        private static bool EncodedStringAndValueAreDifferent(object value, string encodedValue)
        {
            return !value.ToString().Equals(encodedValue);
        }

        private void SetupAllowedStringsDictionary()
        {
            if (string.IsNullOrWhiteSpace(allowedStrings))
            {
                return;
            }

            foreach (var allowedString in allowedStrings.Split(‘,‘).Select(x => x.Trim())
                .Where(allowedString => !allowedStringsDictionary.ContainsKey(allowedString)))
            {
                allowedStringsDictionary.Add(allowedString,
                    EncoderHelper.HtmlEncode(allowedString, false));
            }
        }
        /// <summary>
        /// 设置错误消息
        /// </summary>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        private string SetErrorMessage(ValidationContext validationContext)
        {
            if (IsResourceErrorMessage())
            {
                var resourceManager = new ResourceManager(errorMessageResourceType);
                return resourceManager.GetString(errorMessageResourceName, CultureInfo.CurrentCulture);
            }

            if (!string.IsNullOrEmpty(errorMessage))
            {
                return errorMessage;
            }

            return string.Format(DefaultValidationMessageFormat, validationContext.DisplayName);
        }

        private bool IsResourceErrorMessage()
        {
            return !string.IsNullOrEmpty(errorMessageResourceName) && errorMessageResourceType != null;
        }
    }
时间: 2024-10-09 22:59:14

Magicodes.WeiChat——使用AntiXssAttribute阻止XSS(跨站脚本攻击)攻击的相关文章

目前日向博客对xss跨站脚本注入和sql注入的防范

昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无线循环弹出框的脚本,估计这个脚本之后他再想输入也没法了. 类似这种: <html> <body onload='while(true){alert(1)}'> </body> </html> 我立刻认识到这事件严重性,它说明我的博客有严重安全问题.因为xss跨站脚本攻击可能导致用户Co

XSS跨站脚本攻击原理及防护方法

概念:     XSS(Cross Site Script)跨站脚本攻击.它指的是恶意攻击者往Web 页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web 里面的html 代码会被执行,从而达到恶意用户的特殊目的.本文介绍了该攻击方式,并给出了一些防范措施. 原理: XSS 属于被动式的攻击.攻击者先构造一个跨站页面,利用script.<IMG>.<IFRAME>等各种方式使得用户浏览这个页面时,触发对被攻击站点的http 请求.此时,如果被攻击者如果已经在被攻击站点登录

XSS跨站脚本攻击

[XSS跨站脚本攻击] 1.在Get请求的值中插入代码. $name = $_GET['name']; echo "Welcome $name<br>"; 2.输入框中输入代码. 参考: 1.http://www.cnblogs.com/bangerlee/archive/2013/04/06/3002142.html

XSS:跨站脚本攻击

XSS:跨站脚本,是攻击者向目标web站点注入html标签或者脚本,如果web页面动态的产生文档内容,并且这些内容是基于用户提交的数据,而并没有通过从中移除任何嵌入的html标签来消毒的话,那这个web页面很容易遭到跨站脚本攻击. 例如,如下的web页面,它使用js通过用户的名字来向用户问好: <html> <head><title>test</title></head> <body> <script type="te

PHP漏洞全解(四)-xss跨站脚本攻击

本文主要介绍针对PHP网站的xss跨站脚本攻击.跨站脚本攻击是通过在网页中加入恶意代码,当访问者浏览网页时恶意代码会被执行或者通过给管理员发信息 的方式诱使管理员浏览,从而获得管理员权限,控制整个网站.攻击者利用跨站请求伪造能够轻松地强迫用户的浏览器发出非故意的HTTP请求,如诈骗性的电汇 请求.修改口令和下载非法的内容等请求. XSS(Cross Site Scripting),意为跨网站脚本攻击,为了和样式表css(Cascading Style Sheet)区别,缩写为XSS 跨站脚本主要

初窥XSS跨站脚本攻击

XSS跨站脚本攻击的分类 一. 反射型XSS跨站脚本攻击 二. 存储型XSS跨站脚本攻击 三. 基于DOM的XSS跨站脚本攻击 1.反射性XSS

JAVA覆写Request过滤XSS跨站脚本攻击

注:本文非本人原著. demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca 如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼.为什么呢. 尤其是有富文本编辑器的产品.xss可能出现在http的head,不说别的,新浪多次出现. xss可以出现在post数据的正文.图片的url. 于是各种Xss横行,如今Xss跨站脚本漏洞的流行程度甚至超过了当年的sql. 那么对于JAVA语言,如何防御呢. 笔者分享一个思路:所有的web项目,所有的

python全栈系列之---xss跨站脚本攻击和csrf(xsrf)攻击

xss跨站脚本攻击:恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的. 例如:某些论坛允许用户自由发言,而不对用户的输入数据进行检测,直接显示在页面中. 若是用户输入了某些css样式代码,html表格代码,显示在页面后会改变页面的布局. 若是输入某些js代码,用于获取其他用户的文件,或者修改本地文件,也可以发送用户cookie等信息到自己的计算机中模拟用户登录 一般可以通过函数处理htmlspecial

Fortify漏洞之Cross-Site Scripting(XSS 跨站脚本攻击)

书接上文,继续对Fortify漏洞进行总结,本篇主要针对XSS跨站脚步攻击漏洞进行总结如下: 1.Cross-Site Scripting(XSS 跨站脚本攻击) 1.1.产生原因: 1. 数据通过一个不可信赖的数据源进入 Web 应用程序.对于 Reflected XSS(反射型),不可信赖的源通常为 Web 请求,只影响攻击到当前操作用户:而对于 Persisted(也称为 Stored 持久型)XSS,该源通常为数据库或其他后端数据存储,可能影响多操作用户. 2. 未检验包含在动态内容中的