数据库支持的 Liquid 模板和 Marshal.load 的安全问题
Security concerns with DB backed Liquid Templates and Marshal.load
我将电子邮件模板存储在 PostgreSQL 中,以便用户可以编辑外发电子邮件。我正在使用 Liquid 来防止在服务器上执行代码。为了帮助加快从数据库中获取电子邮件模板、解析它然后呈现它的过程,我想编组 liquid 模板。这是执行此操作的代码:
# 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
会导致远程代码执行。我将编组 a Liquid::Template 对象,但这确实包含可怕用户提供的数据。有什么我需要注意的安全注意事项吗?
理论上是您的实施中的安全问题。
By design, ::load can deserialize almost any class loaded into the
Ruby process. In many cases this can lead to remote code execution if
the Marshal data is loaded from an untrusted source.
As a result, ::load is not suitable as a general purpose serialization
format and you should never unmarshal user supplied input or other
untrusted data.
If you need to deserialize untrusted data, use JSON or another
serialization format that is only able to load simple, ‘primitive’
types such as String, Array, Hash, etc. Never allow user input to
specify arbitrary types to deserialize into.
实际上,在您的情况下,Liquid 会处理任何恶意输入,因此您应该没问题。
就是说,我完全看不出 serializing/deserializing 有任何理由,因为您的模板只是纯文本。当 serializing/deserializing.
时甚至会出现性能损失
我将电子邮件模板存储在 PostgreSQL 中,以便用户可以编辑外发电子邮件。我正在使用 Liquid 来防止在服务器上执行代码。为了帮助加快从数据库中获取电子邮件模板、解析它然后呈现它的过程,我想编组 liquid 模板。这是执行此操作的代码:
# 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
会导致远程代码执行。我将编组 a Liquid::Template 对象,但这确实包含可怕用户提供的数据。有什么我需要注意的安全注意事项吗?
理论上是您的实施中的安全问题。
By design, ::load can deserialize almost any class loaded into the Ruby process. In many cases this can lead to remote code execution if the Marshal data is loaded from an untrusted source.
As a result, ::load is not suitable as a general purpose serialization format and you should never unmarshal user supplied input or other untrusted data.
If you need to deserialize untrusted data, use JSON or another serialization format that is only able to load simple, ‘primitive’ types such as String, Array, Hash, etc. Never allow user input to specify arbitrary types to deserialize into.
实际上,在您的情况下,Liquid 会处理任何恶意输入,因此您应该没问题。
就是说,我完全看不出 serializing/deserializing 有任何理由,因为您的模板只是纯文本。当 serializing/deserializing.
时甚至会出现性能损失