欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

代码分析平台CodeQL学习手记(十一)

来源:本站整理 作者:佚名 时间:2020-01-22 TAG: 我要投稿

在前面的文章中,我们为读者深入介绍了如何利用CodeQL提供的标准类来分析Python项目中的函数、语句、表达式和控制流。在本文中,我们将为读者介绍如何分析数据流,以及如何进行污点跟踪和指向分析。
概述
首先,什么是污点跟踪呢?简单来说,就是分析代码运行过程中,可能存在安全隐患或“受污染”的数据的流动情况。其次,污点跟踪有什么作用呢?作用就很多了,比如,我们可以通过污点跟踪来查明下列情况:用户控制的输入是否存在被恶意利用的隐患?危险的参数是否会传递给易受攻击的函数?机密或敏感的数据是否存在被泄漏的风险?除此之外,在进行其他类型的安全分析过程中,还可以通过这种方法来跟踪各种非法的、不安全或不可信的数据。
污点跟踪与基本数据流的不同之处在于,除了进行“常规的”数据流分析之外,它还考虑到了在不保留值(non-value-preserving)的情况下的数据流分析。例如,在赋值语句dir = path + "/"中,如果path被污染了,那么dir也将被污染,即使从path到path + "/"之间没有数据流动。
对于不同的语言,包括C/C++、C#、Java和JavaScript语言,CodeQL平台都为其提供了独立的、用于处理其“常规”数据流和污点跟踪的库。通过在查询中导入相应的库,我们就可以访问相应的类和谓词,以便处理这些数据流模式。在分析Python代码的时候,我们也可以使用相同的污点跟踪库来分析“常规的”数据流和污点流,同时,我们也可以通过定义额外的数据流属性来区分保留值和不保留值的情况下的处理方法。
污点跟踪与数据流分析
其实,污点跟踪库位于TaintTracking模块中。另外,用于污点跟踪或数据流分析的所有查询都具有三个显式组件(其中一个是可选的),以及一个隐式组件。这些显式组件包括:
1. 一个或多个可能存在不安全数据的源点,它们由TaintTracking::Source类表示。
2. 由TaintTracking::Sink类表示的一个或多个数据或污点可能流向的接收点。
3. 零个或多个清洗器,由Sanitizer类表示。
在数据从源点流向接收点的过程中,如果没有遭到清洗器的拦截的话,用于污点跟踪或数据流分析的查询就会返回相应的分析结果。
这三个组件是通过TaintTracking::Configuration绑定在一起的,以便明确特定查询与哪些源点和接收点相关。
最后一个隐式组件是污点的“kind”,由TaintKind类表示。污点的类型决定了,除了执行内置的、针对“保留值”的处理之外,还执行哪些针对“非保留值”的分析步骤。例如,对于上面讲过的 dir = path + "/",当污点表示字符串的时候,则污点数据会从path流向dir,但如果污点为None的话,则不会出现这种情况。
污点跟踪的局限性
尽管污点跟踪是一种强大的技术,但值得注意的是,它严重依赖于底层的数据流图。然而,要想创建一个准确且覆盖率又高的数据流图,却是一个非常大的挑战,特别是对于像Python这样的动态语言来说。此外,调用图通常也不是很完整的,代码的可达性也很难精确测量,而某些结构,比如eval函数,由于动态性太强了,所以很难进行分析。
利用污点跟踪分析Python代码
一个简单的污点跟踪查询的基本形式如下所示:
/**
 * @name ...
 * @description ...
 * @kind problem
 */
 
import semmle.python.security.TaintTracking
 
class MyConfiguration extends TaintTracking::Configuration {
 
    MyConfiguration() { this = "My example configuration" }
 
    override predicate isSource(TaintTracking::Source src) { ... }
 
    override predicate isSink(TaintTracking::Sink sink) { ... }
 
    /* optionally */
    override predicate isExtension(Extension extension) { ... }
 
}
 
from MyConfiguration config, TaintTracking::Source src, TaintTracking::Sink sink
where config.hasFlow(src, sink)
select sink, "Alert message, including reference to $@.", src, "string describing the source"
作为一个虚构的示例,这里的查询代码想要查找从HTTP请求到名为“unsafe”的函数的数据流。当然,这些源点都是预定义好的,读者可以通过导入semmle.python.web.HttpRequest库来访问它们。此外,接收点则可以通过一个定制的TaintTracking::Sink类来进行定义。
/* Import the string taint kind needed by our custom sink */
import semmle.python.security.strings.Untrusted
 
/* Sources */
import semmle.python.web.HttpRequest
 
/* Sink */
/** A class representing any argument in a call to a function called "unsafe" */
class UnsafeSink extends TaintTracking::Sink {
 
    UnsafeSink() {
        exists(FunctionValue unsafe |
            unsafe.getName() = "unsafe" and
            unsafe.getACall().(CallNode).getAnArg() = this
        )
    }
 
    override predicate sinks(TaintKind kind) {
        kind instanceof StringKind
    }
 
}
 
class HttpToUnsafeConfiguration extends TaintTracking::Configuration {
 
    HttpToUnsafeConfiguration() {
        this = "Example config finding flow from http request to 'unsafe' function"

[1] [2] [3] [4] [5]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载