从Haskell中的“强化静态检查工具”复制“污点模式”

时间:2014-05-06 07:16:00

标签: security haskell coq taint idris

我已经阅读了Fortify静态检查工具的一些文档。此工具使用的概念之一称为 taints 。某些来源(例如Web请求)提供以一种或多种方式受到污染的数据,而某些接收器(例如Web响应)要求数据不受污染。

Fortify的好处是你可以拥有几种类型的污点。例如,您可以使用srand标记NON_CRYPTO_RAND输出,然后在将此变量用于加密目的时要求此污点不存在。其他示例包括非绑定的已检查数字等。

是否可以使用Haskell或其他编程语言中使用的更强大的静态类型系统来模拟污点,使用更复杂的类型系统?

在Haskell中,我可以使用Tainted [BadRandom,Unbounded] Int之类的类型,但使用它们进行计算似乎非常困难,因为这种新类型限制了不会限制污点的操作。

有没有更好的方法来实现这一目标?关于该主题的任何现有工作?

2 个答案:

答案 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)