【问题标题】:Haskell: Is it possible to inject Show and Read?Haskell:可以注入 Show 和 Read 吗?
【发布时间】:2015-11-01 20:38:04
【问题描述】:

我阅读了这封邮件*safe* coerce:four methods compared,其中讨论了类型转换的方法。

在第一种方法中,String 被用作通用表示,每个想要转换为/从其他类型转换的类型只需将自己创建为类型类 ShowRead 的实例。

但是,这会引发安全问题吗?有没有办法让输入劫持进程,类似于 SQL 注入?

【问题讨论】:

  • 在 SQL 注入中,您劫持服务器以执行不允许的命令,因为您确实使用了未经检查的用户输入,所以如果您使用用户输入 unchecked ,当然会遇到同样的问题 .. . 我只是看不出这里的连接在哪里
  • 这在很大程度上取决于您解析的数据能够代表什么样的恶意行为。 SQL 非常强大,当然你可以创建一个与其等效的 Haskell DSL。所以不要execSQL $ read arbitraryString,你就安全了。

标签: haskell


【解决方案1】:

假设攻击者只能提供这些值的文本表示,而对于 SQL 注入,您的意思是执行任意代码作为解析输入的结果:

假设您可以控制ShowRead 的实例,并且小心地保持代码纯净,那么攻击者提供的输入无关紧要,您的代码是纯净的并且没有边-effects,因此不可能有“SQL注入”之类的东西。

显然,攻击者可以提供需要大量时间/资源来解析的输入,但这是一种 DoS 攻击,与类似 SQL 注入的攻击不同。

【讨论】:

    【解决方案2】:

    在我的脑海中,当它不安全时,它是显而易见的。所以基本上:不要相信read 你从任何人那里得到的任何意见。它用于反序列化,因此当您进行反序列化时,请创建一个函数来检查您收到的数据的完整性。

    否则用户可以轻松更改输入(show 产生非常简单的文本),并绕过智能构造函数。解决这个问题的另一种方法是创建自定义的、更安全的实例。例如。许多容器序列化为:fromList [1,2,3] 而不是show 底层结构。不会有太多问题。

    这是一个数据类型的 GHCi 会话,它是一个列表,其大小为 Int

    data LList a = LList [a] Int deriving (Eq, Ord, Show, Read)
    let mkLList xs = LList xs (length xs)
    -- Module would only expose (LList, mkLList)
    read "LList [6,4,2] 6548" :: LList Int
    > LList [6,4,2] 6548
    

    现在我们有一个长度为 6548 个元素的 LList...但我们只有 3 个。

    【讨论】:

    • 这只是由于自动派生的实例。您可以轻松编写ShowRead 的安全版本来检查length 的正确性。这也不像 SQL 注入。这只会创建格式错误的数据,但不会执行任何操作。
    • @Bakuriu 我同意,这就是我在第一句话中所说的“明显方式”的意思。只是不要天真。除此之外,您可能会发现或可能不会发现与 SQL 注入的相似之处,但无论哪种方式,这都可能导致安全问题。即使你只考虑执行:依赖数据的执行只是这个问题发生时间的一个子集,我认为它也非常频繁。
    猜你喜欢
    • 2012-07-05
    • 1970-01-01
    • 2020-08-22
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多