以下方法用于根据用户参数/选择下载YAML文件。
这肯定是不安全的,因为我可以下载层次结构中的其他YAML文件。
def download
language_code = params[:code]
send_file(
"#{Rails.root}/config/locales/#{language_code}.yml",
filename: "#{language_code}.yml",
type: "application/yml"
)
end
我无法把握params[:code]
自然是动态的。
如何在download
这里保护易受攻击的方法?
正如注释所暗示的那样,您的#1选项是完全禁止用户与language_code
字符串进行交互。注释中有许多建议的选项:受限列表,数据库实现等。
另一个选择(尽管考虑到您的约束,这可能无效)是进行长度检查:language_code.length <= 4
。假设您的语言代码不超过Wikipedia的语言代码列表中的4个字符。
作为最后的选择,您还可以清理用户输入并清理它,以使文件路径无法被操纵。我在这里写了一篇有关文件清理功能的文章。您有两种选择:
A-Z, a-z, 0-9
/ \ ? % * : | " < > . (and space)
对于您的情况(我假设您完全控制config/locals
),我会将其列入白名单。白名单功能易于创建:
def sanitize(file_name)
# Remove any character that aren't 0-9, A-Z, or a-z
filename.gsub(/[^0-9A-Z]/i, '_')
end
不知道您的语言文件是如何实现的,您可能需要使用下划线以外的字符_
进行替换。
为了额外的预防措施,您还可以预先检查目录以查看文件是否存在,以防止路径遍历攻击。像这样:
def valid_path?(filename)
Dir["#{Rails.root}/config/locales/*"].include?("#{Rails.root}/config/locales/#{filename}")
end
这样做的好处是,您明确声明文件在config/locales
提供之前必须存在于目录中。如果攻击者尝试进行目录遍历攻击,则此函数将返回false。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句