`
liuqiang
  • 浏览: 162071 次
  • 性别: Icon_minigender_1
  • 来自: 华东
社区版块
存档分类
最新评论

Rails中html_escape和sanitize

    博客分类:
  • Ruby
阅读更多

       一般来说,通常使用input的field都会做一些filter的动作,避免被不怀好意之徒塞一些危险的 HTML code(script等)进去搞破坏。在ROR中,我们在前面加一个h()(一般不用括号?不容易看到?)即可,h在ROR中起什么作用呢?它是 html_escape的alias(别名),它会将所有的"<xx>"变成&lt;,&gt,比如:
js 代码<script>alert('a');</script>会变成:    &lt;script&gt;alert('a');&lt;/script&gt;
这样就完全做不了乱了。因为所有的tag都被搞掉了。这样太严格了,有时候我们需要开放一些字体,颜色等tag给用户使用,用h()就不行了,正好ROR中还有个方法,sanitize()这个方法可以帮你实现这个愿望。ROR API中:
       Sanitizes the given HTML by making form and script tags into regular text, and removing all "onxxx" attributes (so that arbitrary Javascript cannot be executed). Also removes href attributes that start with "javascript:".
       
      它会砍掉script这个tag,以及onXxxx之类的attribut,你没有机会执行javascript,但是你还可以塞一些div或iframe之类的tag让你的版面烂掉。

      所以我们需要自定义一个html filter,可以自由的指定我们放行的那些tag。网上发现了这个sanitize.rb,完美的帮我们实现愿望。如何使用:
第一行:
ruby 代码
  1. def sanitize( html, okTags='a href, b, br, i, p' )  
okTags代表就是允许的tag,目前有a,b,br,i,p之类的tag,如果输入<iframe>xxx</iframe>之类的不允许的code,就会出现
xxx.不允许的结果都将被砍掉。如果想增加span,或font这样的tag,则可以:
ruby 代码
  1. def sanitize( html, okTags='a href, b, br, i, p, span, font' )  

a href之间没有用逗号隔开,是代表sanitize允许a这个tag使用href这个attribute,比如:
<a href="http://blackanger.iteye.com" _fcksavedurl="http://lightyror.blogspot.com" target="_blank">Haha</a>
只会出现: <a href=http://blackanger.iteye.com>Haha</a>,只有href这个属性可以保留,其他的被无情的砍掉。当我们输入这样的代码:
            <a href=http://blackanger.iteye.com>Haha
会自动帮你补齐tag:

            <a href=http://blackanger.iteye.com>Haha</a>

Put the following code in your helper:
#
# $Id: sanitize.rb 3 2005-04-05 12:51:14Z dwight $
#
# Copyright (c) 2005 Dwight Shih
# A derived work of the Perl version:
# Copyright (c) 2002 Brad Choate, bradchoate.com
#
# Permission is hereby granted, free of charge, to
# any person obtaining a copy of this software and
# associated documentation files (the "Software"), to
# deal in the Software without restriction, including
# without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to
# whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission
# notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
# OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
# OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#

def sanitize( html, okTags='a href, b, br, i, p' )
# no closing tag necessary for these
soloTags = ["br","hr"]

# Build hash of allowed tags with allowed attributes
tags = okTags.downcase().split(',').collect!{ |s| s.split(' ') }
allowed = Hash.new
tags.each do |s|
    key = s.shift
    allowed[key] = s
end

# Analyze all <> elements
stack = Array.new
result = html.gsub( /(<.*?>)/m ) do | element |
    if element =~ /\A<\/(\w+)/ then
      # </tag>
      tag = $1.downcase
      if allowed.include?(tag) && stack.include?(tag) then
        # If allowed and on the stack
        # Then pop down the stack
        top = stack.pop
        out = "</#{top}>"
        until top == tag do
          top = stack.pop
          out << "</#{top}>"
        end
        out
      end
    elsif element =~ /\A<(\w+)\s*\/>/
      # <tag />
      tag = $1.downcase
      if allowed.include?(tag) then
        "<#{tag} />"
      end
    elsif element =~ /\A<(\w+)/ then
      # <tag ...>
      tag = $1.downcase
      if allowed.include?(tag) then
        if ! soloTags.include?(tag) then
          stack.push(tag)
        end
        if allowed[tag].length == 0 then
          # no allowed attributes
          "<#{tag}>"
        else
          # allowed attributes?
          out = "<#{tag}"
          while ( $' =~ /(\w+)=("[^"]+")/ )
            attr = $1.downcase
            valu = $2
            if allowed[tag].include?(attr) then
              out << " #{attr}=#{valu}"
            end
          end
          out << ">"
        end
      end
    end
end

# eat up unmatched leading >
while result.sub!(/\A([^<]*)>/m) { $1 } do end

# eat up unmatched trailing <
while result.sub!(/<([^>]*)\Z/m) { $1 } do end

# clean up the stack
if stack.length > 0 then
    result << "</#{stack.reverse.join('></')}>"
end

result
end

分享到:
评论

相关推荐

    inspinia admin - v2.5 Rails_Full_Version

    当你解压"Rails_Full_Version"并开始开发时,可以参考这些知识点逐步构建和定制你的后台管理系统。务必保持代码整洁,遵循DRY(Don't Repeat Yourself)原则,以实现高效且可扩展的代码。同时,不断学习和研究新的...

    rails_semantic_logger, Rails 语义记录器用语义记录器替换 Rails 缺省记录器.zip

    rails_semantic_logger, Rails 语义记录器用语义记录器替换 Rails 缺省记录器 Rails 语义记录器 语义记录器用语义记录器替代 Rails 缺省记录器。http://github.com/rocketjob/rails_semantic_logger文档有关完整文档...

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板.zip

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板 Rails 应用编辑器 Rails 应用程序编辑器 gem 安装一个 命令行 工具来从"食谱"的Collection 组装 Rails 应用程序。"你可以使用 rails_...

    InspiniaAdmin 2.6.1 Rails_Full_Version

    在Rails_Full_Version压缩包中,包含了完整的源代码和必要的资源文件,开发者可以通过解压并导入到Rails项目中,按照官方文档进行配置和定制。同时,这个版本可能还包含了升级记录、更改日志和可能的bug修复,以保证...

    agile_web_development_with_rails_3rd_edition.9994652073.pdf

    此外,书中还穿插了大量的实践案例和代码示例,帮助读者理解并掌握Rails的高级特性。 ### 总结 《敏捷Web开发与Rails》第三版是一本全面且深入的Ruby on Rails教程,适合那些希望利用敏捷开发原则和Rails框架构建...

    rails_best_practices:Rails项目的代码度量工具

    rails_best_practices ...默认情况下,rails_best_practices将解析vendor , spec , test和features目录中的代码。 排除目录 要排除目录,只需使用-e或--exclude调用: rails_best_practices -e "db/migrate

    inspinia admin - v2.5 Rails_Seed_Project

    本文将详细探讨其在Rails框架下的种子项目(Rails_Seed_Project),旨在帮助开发者更好地理解和运用这一强大的工具。 首先,我们来了解一下“Inspinia Admin”。这是一款基于Bootstrap 3构建的响应式后台模板,提供...

    InspiniaAdmin 2.5 Rails_Seed_Project

    在这个Rails_Seed_Project中,开发者可以找到一个典型的Rails应用结构,包括Gemfile、config.ru、database.yml等核心配置文件,以及models、controllers、views和assets等目录,它们分别对应着业务逻辑、数据操作、...

    rails_email_preview, 在 Rails 中,预览和编辑应用程序邮件程序模板.zip

    rails_email_preview, 在 Rails 中,预览和编辑应用程序邮件程序模板 Rails 电子邮件预览 使用这里 Rails 引擎在浏览器中预览电子邮件。 兼容 Rails 4.2 。电子邮件审阅: 所有电子邮件预览的列表: 代表有两个主题...

    Rails_3_Cheat_Sheets.pdf

    Rails_3_Cheat_Sheets.pdf

    RestFul_Rails_Dev_pdf_v_0.1.zip

    本资料“RestFul_Rails_Dev_pdf_v_0.1.zip”包含了《RESTful Rails Development》的翻译版,将深入探讨如何在Rails中实现RESTful的设计模式。 首先,RESTful设计的核心概念是资源(Resources)。在Rails中,资源...

    InspiniaAdmin 2.5 Rails_full_version

    InspiniaAdmin 2.5 Rails_full_version

    rails_admin_acts_as_list:rails_admin插件以对记录进行排序

    在您的config/initializers/rails_admin.rb初始化程序中添加配置: RailsAdmin . config do | config | config . model Post do list do sort_by :position # Add Default sorting sort_reverse false # sort p

    inspinia_admin_v2.5_Rails_Full_Version

    该模板包含的文件列表“inspinia_admin_v2.5_Rails_Full_Version”很可能包括以下组成部分: 1. **静态资源**:CSS样式文件、JavaScript脚本和图像资源。这些文件用于构建用户界面,包括响应式布局、图表、表单元素...

    Ruby新手学习书(Ruby语言中文教程)和Rails_4_days

    "Ruby新手学习书"和"Rails_4_days"这两个资源是为初学者设计的,旨在帮助他们快速掌握Ruby语言的基础以及Rails框架的核心概念。 在Ruby语言中文教程中,你将学到以下关键知识点: 1. **基础语法**:Ruby的语法简洁...

    Rails101_by_rails4.0

    书中介绍了Ruby on Rails安装的最佳实践,以及如何通过Git、编辑器和Linux命令行等前置技能的学习,为后续的Rails开发打下基础。Git作为版本控制系统,对于团队协作开发项目尤为重要,学习它的使用方法能够帮助...

Global site tag (gtag.js) - Google Analytics