【问题标题】:Alternatives to "eval" for ActiveSupport date parsingActiveSupport 日期解析的“eval”替代方案
【发布时间】:2016-01-29 01:19:18
【问题描述】:

我的脚本目前接受 ActiveSupport 日期字符串作为命令行参数:

my_script --mindate 1.day

在我的脚本中,我使用 eval 将其存储到我的配置中

MyScript.configuration.min_date = eval(min_date_string)

我知道这是非常狡猾和不安全的,因为任何东西都可以传递给 eval,但是我的替代方案是什么?

【问题讨论】:

    标签: ruby metaprogramming activesupport


    【解决方案1】:

    您想要持续时间?我想你可以使用chronic_duration

     my_script --mindate "1 day"
     MyScript.configuration.min_date = ChronicDuration.parse(min_date_string)
    

    但由于它是自然语言启发式算法,因此无法完全准确地定义它可以识别的字符串类型。但它会做一些花哨的事情,比如“1 天零 4 小时”。

    或者您可以为参数编写自己的非常简单的解析器/解释器。只需拆分空格(用于“1 天”类型的输入)或句点(用于“1.day”)类型的输入。识别第二个位置的几个单词(“小时”、“分钟”、“日”、“月”、“年”),将它们转换为秒,将数字乘以转换为秒的单词。大概有十几行红宝石。

    或者,您甚至可以利用支持“1.day”等内容的 ActiveSupport 功能,使其更加轻松。

      str = "11 hours"
      number, unit = str.split(' ')
      number.to_i.send(unit)
    

    这将让命令行用户将他们想要的任何方法发送到一个数字。我不确定这是否重要。就此而言,我不确定原来的eval 是否真的很重要——但我同意你的看法,这是不好的做法。就此而言,用户输入上的send 可能也是如此,尽管没有那么糟糕。

    或者您可以让他们发送原始秒数并自行计算。

    my_script --mindate 86400
    

    您意识到1.day 最终会被转换为标准日的秒数,对吧?我不知道你为什么叫几秒钟“mindate”,但那是你的事!

    编辑或者另一种选择,让他们这样做:

    my_script --mindays 2 --minhours 4 --minminutes 3
    

    什么的。

    【讨论】:

      【解决方案2】:

      你的脚本是如何被调用的?这是否总是由在运行它的任何机器上拥有帐户的用户调用?这会以某种方式被 Web 服务调用,还是以某种方式让无法访问机器的人能够使用自己的参数远程调用它?

      如果它只会被用户调用,并且这些用户已经可以访问ruby 命令或irb,那么你并不能让他们做任何他们通过调用 eval 做不到的事情.

      如果它被远程调用,您可能不应该使用 eval。或者,一个快速而肮脏的解决方案可能是匹配您将使用正则表达式评估的模式。 /^[0-9]+(\.[a-z_0-9]+){,2}$/ 之类的东西会确保在评估之前它在 Fixnum 文字的 2 个方法调用内。

      【讨论】:

      • 我同意你的看法,这可能没什么大不了的。但可能比抱歉更安全。当然,具有命令行访问权限的人已经可以执行他们想要的任何 ruby​​。但是然后你编写了你的​​实用程序,然后你最终以某种方式使用它,可能会对其进行炮轰,这样它最终会被从 remote 用户输入传入的参数调用,哎呀你只是给了远程用户RCE,你可能永远不会意识到它,因为它经历了几个步骤,你忘记了命令行的arg最终被评估了。
      猜你喜欢
      • 2010-10-31
      • 2012-03-13
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-10
      相关资源
      最近更新 更多