我正在使用rails应用程序,有两个相当重要的模型,即Reminder和Matcher。
class Reminder < ActiveRecord::Base
end
提醒允许用户设置自己的日程表来执行某些操作,因此我有一个名为&#34; condition&#34;的文本字段。我允许他们输入他们自己的红宝石代码。
例如,他们可以输入:
Date.today.friday?
如果他们想要每周五提醒一下。我这样做是为了让用户能够创建自己的提醒方式具有极大的灵活性。
然后我有一个预定的cron任务,它遍历所有提醒并检查它们的状况并对它们采取行动,如:
For reminder in Reminder.all
if eval(reminder.condition)
# do something
end
end
此方法的另一个用例是我在匹配模型中使用条件,这是一个难以解释的但我实际上允许用户在该条件下访问关联的模型数据,例如条件可能是:
@matcher.parent.name == "Father" && @matcher.parent.children.count < 10
我知道eval
用户输入的内容非常可怕,所以我正在对模型进行一些验证,以防止一些&#34;讨厌&#34;像&#34;删除,销毁等等#34;我已经构建了一个小型的就地代码编辑器,其中包含一些将代码插入ACE编辑器的菜单。
我喜欢它的工作方式,因为它可以让用户获得最大的灵活性。
如果不使用eval,如何实现?
答案 0 :(得分:0)
您无法信任用户输入。阻止某些单词不会阻止更有想象力的技术,如发送[“d-e-s-t-r-o-y”.split(' - ')。join('')]或更糟。
如果您真的想要这样做,您可以进行改进,在另一个用户帐户的硬化虚拟机中远程验证它,并验证该命令的stdout输出是否与日期格式匹配。如果允许任何代码执行,即使是人们也可以到处走。
对于更强大的代码,您应该编写一个想要允许的显式内容的DSL。白名单比黑名单更安全,因为没有人能够聪明地击败世界其他地方的想象力。