我已经阅读了Fortify静态检查工具的一些文档。此工具使用的概念之一称为 taints 。某些来源(例如Web请求)提供以一种或多种方式受到污染的数据,而某些接收器(例如Web响应)要求数据不受污染。
Fortify的好处是你可以拥有几种类型的污点。例如,您可以使用srand
标记NON_CRYPTO_RAND
输出,然后在将此变量用于加密目的时要求此污点不存在。其他示例包括非绑定的已检查数字等。
是否可以使用Haskell或其他编程语言中使用的更强大的静态类型系统来模拟污点,使用更复杂的类型系统?
在Haskell中,我可以使用Tainted [BadRandom,Unbounded] Int
之类的类型,但使用它们进行计算似乎非常困难,因为这种新类型限制了不会限制污点的操作。
有没有更好的方法来实现这一目标?关于该主题的任何现有工作?
答案 0 :(得分:4)
不是一个完整的解决方案(=很好的现有方法),但有一些提示:
我所知道的关于Haskell中安全信息流的两篇论文是Li and Zdanevic, 2006(其中一位作者也参与了Jif)和Russo et al., 2008。两者都接近你的污点"从相反的方面来看,即通过标记值来确定它们的安全性,并使用网格结构来排序不同的安全级别 - 但解决的问题应与您描述的相同。 / p>
第一种方法使用箭头传递安全信息和值(类似于StaticArrow
,我认为),因此动态检查信息流策略(即,如果您尝试访问值,则会发生运行时错误你不被允许访问)。
第二个基本上使用带有类型标记索引的标识monad,指示所包含值的安全级别,从而在编译时运行。但是,为了在不同的安全级别和更复杂的东西之间进行转换,它们在monad周围使用IO
包装器,因此它们的系统不再是完全静态的。正如您在评论中提到的,问题的根源似乎是不同标记的monad的不兼容性。
当我为一个单一的研讨会调查这些论文时,我也重新实现了一些代码,然后玩弄它,试图避免诉诸IO
。其中一个结果是this;也许这种修改可能是一个有用的实验(尽管我没有做任何真正的测试)。
最后,我真正希望看到的一件事是将这些方法与依赖类型相结合。将Agda的全部功能应用于此类任务似乎是正确的方向......
答案 1 :(得分:3)
一个简单的模型可能如下:
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeOperators #-}
module Taint ( (:+), srand, BadRandom, Unbounded, Tainted (), (<+>)) where
import Control.Applicative
import Control.Monad.Identity
data a :+ b
data BadRandom
data Unbounded
newtype Tainted taint a = Tainted { clean :: Identity a }
deriving ( Functor, Applicative, Monad )
(<+>) :: Tainted t1 (a -> b) -> Tainted t2 a -> Tainted (t1 :+ t2) b
Tainted (Identity f) <+> Tainted (Identity x) = Tainted (Identity (f x))
srand :: IO (Tainted BadRandom Int)
srand = undefined
由于clean
未导出,srand
的用户无法删除Tainted
标记。此外,您可以使用“伪 - Applicative
”应用函数(<+>)
来合并污点。我们也可以轻松地为“伪 - Monad
”接口生成类似的组合器:
(>>-) :: Tainted t1 a -> (a -> Tainted t2 b) -> Tainted (t1 :+ t2) b
Tainted (Identity a) >>- f = let Tainted (Identity b) = f a in Tainted (Identity b)