我将电子邮件模板存储在PostgreSQL中,以便用户可以编辑传出的电子邮件。我使用Liquid来防止代码在服务器上执行。为了帮助加快从数据库获取电子邮件模板、对其进行解析,然后进行渲染的过程,我想对液体模板进行Marshal处理。以下是执行此操作的代码:
# Saving template to the db
text = "template text from possibly dangerous user {{stuff}}"
template = Liquid::Template.parse(text)
email_template = EmailTemplate.new # the db class
email_template.source = Marshal.dump(template)
email_template.save
# time goes by and now we need that template
template = Marshal.load(email_template.source) # !! Is this dangerous? !!
我已经读到Marshal.load
可以导致远程代码执行。我将封送一个Liquid::Template对象,但它确实包含可怕用户提供的数据。我需要注意哪些安全方面的考虑吗?
理论上,在您的实现中存在安全问题。
来自Ruby文档:
根据设计,::load几乎可以反序列化加载到Ruby进程。在许多情况下,如果Marshal数据是从不受信任的源加载的。
因此,::load不适合作为通用序列化格式,并且永远不应该分解用户提供的输入或其他不可信数据。
如果需要反序列化不受信任的数据,请使用JSON或其他只能加载简单的"基元"的序列化格式类型,如String、Array、Hash等。从不允许用户输入指定要反序列化为的任意类型。
实际上,在您的情况下,任何恶意输入都会由Liquid处理,所以您应该没事。
也就是说,我真的看不出有任何理由进行序列化/反序列化,因为您的模板只是纯文本。串行化/反序列化时甚至会带来性能损失。