`
bianku
  • 浏览: 72355 次
  • 性别: Icon_minigender_1
  • 来自: 常州
社区版块
存档分类
最新评论

关键字过滤解决方案

阅读更多
关键字过滤功能自然无比重要,但是如果要在代码中对每个输入进行检查和替换则会是一件非常费神费事的事情。尤其是如果网站已经有了一定规模,用户输入功能已经遍及各处,而急需对所有输入进行关键字过滤时,上述做法更可谓“远水解不了近渴”。这时候,如果有一个通用的办法,呼得一下为整站的输入加上了一道屏障,那该是一件多么惬意的事情。这就是本文希望解决的问题。是不是很简单?我一开始也这么认为,不过事实上并非那么一帆风顺,而且在某些特定条件下似乎更是没有太好的解决方法……

  您慢坐,且听我慢慢道来……

实现似乎很简单
  数据结构中的单向链表可谓无比经典。有人说:单向链表的题目好难啊,没法逆序查找,很多东西都不容易做。有人却说:单向链表既然只能向一个方向遍历,那么变化就会很有限,所以题目不会过于复杂。老赵觉得后者的说法不无道理。例如在现在的问题上,我们如果要在一个ASP.NET应用程序中做一个统一的“整站方案”,HttpModule似乎是唯一的选择。

  思路如下:我们在Request Pipeline中最早的阶段(BeginRequest)将请求的QueryString和Form集合中的值做过滤,则接下来的ASP.NET处理过程中一切都为“规范”的文字了。说干就干,不就是替换两个NameValueCollection对象中的值吗?这再简单不过了:

public class FilterForbiddenWordModule : IHttpModule
{
    void IHttpModule.Dispose() { }

    void IHttpModule.Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(OnBeginRequest);
    }

    private static void OnBeginRequest(object sender, EventArgs e)
    {
        var request = (sender as HttpApplication).Request;
        ProcessCollection(request.QueryString);
        ProcessCollection(request.Form);
    }

    private static void ProcessCollection(NameValueCollection collection)
    {
        var copy = new NameValueCollection();

        foreach (string key in collection.AllKeys)
        {
            Array.ForEach(
                collection.GetValues(key),
                v => copy.Add(key, ForbiddenWord.Filter(v)));
        }

        collection.Clear();
        collection.Add(copy);
    }
}
  在BeginRequest阶段,我们将调用ProcessCollection将QueryString和Form两个NameValueCollection中的值使用ForbiddenWord.Filter方法进行处理。ForbiddenWord是一个静态类,其中的Filter方法会将原始字符串中的敏感字符使用“**”进行替换。替换方法不在本文的讨论范围内,因此我们就以如下方式进行简单替换:

public static class ForbiddenWord
{
    public static string Filter(string original)
    {
        return original.Replace("FORBIDDEN_WORD", "**");
    }
}
  看似没有问题,OK,随便打开一张页面看看……

Collection is read-only.Description: An unhandled exception occurred during the execution of the current web request... 
Exception Details: System.NotSupportedException: Collection is read-only.  呀,只读……这是怎么回事?不就是一个NameValueCollection吗?在不得不请出.NET Reflector之后,老赵果然发现其中有猫腻……

public class HttpRequest
{ 
    ...

    public NameValueCollection Form
    {
        get
        {
            if (this._form == null)
            {
                this._form = new HttpValueCollection();
                if (this._wr != null)
                {
                    this.FillInFormCollection();
                }
                this 
._form.MakeReadOnly(); } if (this._flags[2]) { this._flags.Clear(2); ValidateNameValueCollection(this._form, "Request.Form"); } return this._form; } } ... } 
  虽然HttpRequest.Form属性为NameValueCollection类型,但是其中的_form变量事实上是一个HttpValueCollection对象。而HttpValueCollection自然是NameValueCollection的子类,而造成其“只读”的最大原因便是:

[Serializable]
internal class HttpValueCollection : NameValueCollection
{ 
    ...

    internal void MakeReadOnly()
    {
        base.IsReadOnly = true;
    } 

    ...
}
  IsReadOnly是定义在NameValueCollection基类NameObjectCollectionBase上的protected属性,这意味着如果我们只有编写一个如同NameValueCollection或HttpValueCollection般的子类才能直接访问它,而现在……反射吧,兄弟们。

public class FilterForbiddenWordModule : IHttpModule
{
    private static PropertyInfo s_isReadOnlyPropertyInfo;

    static FilterForbiddenWordModule()
    {
        Type type = typeof(NameObjectCollectionBase);
        s_isReadOnlyPropertyInfo = type.GetProperty(
            "IsReadOnly",
            BindingFlags.Instance | BindingFlags.NonPublic);
    }

    ...

    private static void ProcessCollection(NameValueCollection collection)
    {
        var copy = new NameValueCollection();

        foreach (string key in collection.AllKeys)
        {
            Array.ForEach(
                collection.GetValues(key),
                v => copy.Add(key, ForbiddenWord.Filter(v)));
        }

        // set readonly to false.
        s_isReadOnlyPropertyInfo.SetValue(collection, false, null);

        collection.Clear();
        collection.Add(copy);

        // set readonly to true.
        s_isReadOnlyPropertyInfo.SetValue(collection, true, null);
    }   
}  现在再打开个页面看看,似乎没事。那么就来体验一下这个HttpModule的功效吧。我们先准备一个空的aspx页面,加上以下代码:

<form id="form1" runat="server">
    <asp:TextBox runat="server" TextMode="MultiLine" />
    <asp:Button runat="server" Text="Click" />
</form>
  打开页面,在文本框内填写一些敏感字符并点击按钮:

 

  嗨,效果似乎还不错!

问题来了
  太简单了,是不?

  可惜问题才刚开始:如果业务中有些字段不应该被替换怎么办?例如“密码”。如果我们只做到现在这点,那么密码“let-us-say-shit”和“let-us-say-fuck”则会被认为相同——服务器端逻辑接收到的都是“let-us-say-**”。也就是说,我们必须提供一个机制,让上面的HttpModule可以“忽略”掉某些内容。
如果是其他一些解决方案,我们可以在客户端进行一些特殊标记。例如在客户端增加一个“-noffw-password”字段来表示忽略对“password”字段的过滤。不过根据著名的“Don't trust the client”原则,这种做法应该是第一个被否决掉的。试想,如果某些哥们发现了这一点(别说“不可能”),那么想要绕开这种过滤方式实在是一件非常容易的事情。不过我们应该可以把这种“约定”直接运用在字段名上。例如原本我们如果取名为“password”的字段,现在直接使用“-noffw-password”,而HttpModule发现了这种前缀就会放它一马。由于字段的命名完全是由服务器端决定,因此采取这种方式之后客户端的恶人们就无法绕开我们的过滤了。

  还有一种情况就是我们要对某些特定的字段采取一些特殊的过滤方式。例如,之前相当长的一段时间内我认为在服务器端反序列化一段JSON字符串是非常不合理的,不过由于AJAX几乎成了事实标准,亦或是现在的Web应用程序经常需要传递一些结构复杂的对象,JSON格式已经越来越多地被服务器端所接受。假如一个字段是表示一个JSON字符串,那么首先我们只应该对它的“值”进行过滤,而忽略其中的“键”。对于这种字段,我们依旧可以使用如上的命名约定来进行忽略。例如,我们可以使用-json-data的方法来告诉服务器端这个字段应该被当作JSON格式进行处理

 

分享到:
评论

相关推荐

    部分关键字过滤,防止用户使用一些不合理的名称注册

    3. **云服务解决方案**:随着云计算技术的发展,越来越多的服务商提供基于云的关键字过滤服务。这种方式的优点在于无需过多关注底层技术细节,只需要按照API调用即可完成功能部署,并且能够轻松应对大规模流量冲击。...

    指定数据库关键字过滤

    "指定数据库关键字过滤"是一个针对大数据量数据库的优化解决方案,尤其适用于需要快速定位特定信息的场景。这个程序能够在短时间内完成对大量数据的扫描,如100万篇文章数据仅需不到一分钟,充分展示了其出色的性能...

    soft_非法关键字过滤器 v2.2 .zip.zip

    总的来说,《soft_非法关键字过滤器 v2.2 .zip.zip》提供了一套有效的解决方案,帮助用户管理和过滤文本中的非法关键字,维护网络空间的秩序。用户在使用过程中,应详细阅读软件文档,正确理解和应用各项功能,以...

    ASP实例开发源码-非法关键字过滤管理系统 v1.0.zip

    这个实例开发源码——非法关键字过滤管理系统v1.0是基于ASP技术实现的一个功能,旨在帮助网站管理员有效管理和过滤掉用户提交内容中的非法或敏感词汇。 系统的核心功能可能包括以下几个方面: 1. 关键字库:系统会...

    基于倒排索引的可验证混淆关键字密文检索方案.pdf

    这种加密方法允许在不解密的情况下对密文进行计算,从而过滤掉不包含目标关键字的密文数据。这样可以显著减少用户与云服务器之间的数据传输量,提高系统效率。 验证机制是该方案的另一个关键特点。双线性映射被用来...

    支持灵活访问控制的多关键字搜索加密方案.docx

    以上内容详细阐述了可搜索加密技术的发展历程,以及当前研究中的关键挑战和解决方案,特别是本文提出的方案如何通过聚类、访问控制和多关键字搜索优化搜索性能和数据安全性。这些技术对于云服务环境中的数据安全和...

    神州数码防火墙解决方案

    完整的安全解决方案应该覆盖网络的各个层次,并且与安全管理相结 合。神州数码防火墙可以在网络层、传输层和应用层上进行数据的安全保护和过滤。DCFW-1800是典型的多功能防火墙,涵盖了防火墙的技术和特性,具有防止...

    文章多关键字检测高亮

    总的来说,"文章多关键字检测高亮"工具结合了文本处理、用户界面设计和.NET 2.0技术,为用户提供了高效、直观的文本关键字检测解决方案。这样的工具在新闻审查、社交媒体监控、企业内部信息安全管理等多个领域都有...

    防泄密项目解决方案.docx

    防泄密项目解决方案 防泄密项目解决方案是指通过信息安全管理软件与管理规定的实施,从信息安全——防止单位重要信息的泄漏保证单位信息资产安全;行为管理——停止“网络旷工”营造健康工作氛围提高工作效率;系统...

    Html文件关键字搜索

    例如提供的"Html文件关键字搜索"项目可能就是一个这样的工具,通过解压提供的`.sln`和`.suo`文件(这是Visual Studio项目的解决方案和用户选项文件),我们可以看到一个C#项目,该项目可能实现了HTML关键字搜索的...

    防泄密解决方案.pdf

    网页过滤则通过URL库分类和关键字过滤,防止访问不良网站。发帖过滤则限制特定论坛的发帖行为,防止不当言论的传播。邮件过滤通过关键字、收发地址和附件管理,防止通过电子邮件泄露敏感信息。 总结而言,防泄密...

    论坛BBS最新敏感词语不良词语过滤(批量)

    "论坛BBS最新敏感词语不良词语过滤(批量)"这一主题就是针对这一需求提出的解决方案。本文将详细探讨如何在Discuz! 论坛系统中实现批量过滤敏感和不良词语,以及词语过滤的重要性。 Discuz! 是一款广泛应用的开源...

    CTMS.rar_ct_垃圾邮件_垃圾邮件过滤_邮件 过滤

    CTMS(未给出全称)是一个针对这一问题设计的解决方案,它集成了邮件的收发功能,并且具备强大的垃圾邮件过滤机制,旨在为用户提供高效、安全的邮件管理体验。 CTMS的核心功能之一是邮件的收发。用户可以通过CTMS...

    深信服上网行为管理解决方案.pdf

    深信服上网行为管理解决方案是深信服科技有限公司提供的一种全面的网络安全管理工具,旨在帮助企业或组织解决在互联网使用过程中可能遇到的各种问题,包括效率、安全、法律等风险。本解决方案详细介绍了深信服上网...

    基于LD算法的SQL注入攻击过滤方法研究.pdf

    综上所述,基于LD算法的SQL注入攻击过滤方法,以其在过滤效率和准确率上的优势,为当前Web安全领域提供了一个有效的解决方案。但同时,我们也要意识到,SQL注入攻击的防御是一个动态的、持续的过程,需要安全专家和...

    深信服上网行为管理解决方案构建招商银行前沿网络安全.docx

    通过URL过滤和关键字过滤技术,深信服的产品能够阻止员工访问不良网站,降低引入恶意软件的风险。同时,所有访问行为都会被记录,以便追溯和审计,确保网络活动的合规性。 4. **日志管理和审计**: 日志信息的...

    东方电气自控公司邮件网络安全解决方案

    通过邮件内容关键字过滤、收发件人过滤、附件内容过滤等多种策略,有效拦截垃圾邮件和病毒邮件。此外,系统还能进行特定设置,如阻止特定网段邮件、限制连接频率等,防止恶意攻击。即使被过滤的邮件也能被记录下来,...

Global site tag (gtag.js) - Google Analytics