Today's the day

在那毁灭之路,逆流而上


自写 html 闭合的一个 Bug

用 File.expand_path 过滤文件名

galeki posted @ 2008-06-15 12:57AM in Ruby&Rails进修
用 Ruby 求定积分

一些情况下,要从用户哪里得到文件名或者目录名参数,比如文件读取、上传、删除,创建目录,还有 typo 那个 theme_controller 中的 css 和 js 缓存。

恶意用户可以输入含有 "../.." 这样的字符的参数,从而跳转到上级目录,读取或者删除一些其他目录的文件,所以必须要过滤,比如 typo 的 theme_controller.rb 代码中:

  1. def render_theme_item(type, file, mime = nil)
  2.   ...
  3.   if file.split(%r{[\\/]}).include?("..")
  4.     return (render :text => "Not Found", :status => 404)
  5.   end
  6.   ...

file 来自 params[:filename],检查 file 中是否含有 "..",如果有的话,就不做任何动作返回 404。

但是这样并不能解决所有的问题,参数可以被 URI 编码成 %xx%xx 的形式,而且天知道还有什么字符可以跳转到上级目录

最近在看 《Adcanced Rails》这书,上面写了种不错的方法:

  1. name = params[:filename]
  2.  
  3. base_path = File.expand_path(File.join(RAILS_ROOT, "public"))
  4. file_path = File.join(base_path, name)
  5.  
  6. if File.expand_path(file_path).start_with?(base_path)
  7.   data = File.read(file_path)
  8. else
  9.   raise "Access denied"
  10. end

File.expand_path 这方法可以扩展路径字符中所有的特殊字符,包括 "~", "..", ".",形成平坦的路径字符串( 原来我一直以为 File.join 也有这个功效…… ),最后只要检查一下文件的最终地址,开头是否为安全的目录即可,这样就可以轻松的将用户的读取范围限制在 base_path 之下了~

 

全局相关文章
  • No match
相关文章
  • No match

Comments Feed


* Login
*