从代码更改中推断密码学API规则

Inferring Crypto API Rules from Code Changes


Remark

Full Paper: https://files.sri.inf.ethz.ch/website/papers/diffcode-pldi2018.pdf
Video: https://www.youtube.com/watch?v=vl-w5KFO0II

Abstract

Creating and maintaining an up-to-date set of security rules that match misuses of crypto APIs is challenging, as crypto APIs constantly evolve over time with new cryptographic primitives and settings, making existing ones obsolete.

To address this challenge, we present a new approach to extract security fixes from thousands of code changes. Our approach consists of: (i) identifying code changes, which often capture security fixes, (ii) an abstraction that filters irrelevant code changes (such as refactorings), and (iii) a clustering analysis that reveals commonalities between semantic code changes and helps in eliciting security rules.

We applied our approach to the Java Crypto API and showed that it is effective: (i) our abstraction effectively filters non-semantic code changes (over 99% of all changes) without removing security fixes, and (ii) over 80% of the code changes are security fixes identifying security rules. Based on our results, we identified 13 rules, including new ones not supported by existing security checkers.


Introduction

它的背景是这样的。目前许多数据泄露的案例都是由于Crypto API的不正确使用造成的。开发人员对Crypto API的错误使用,或者是某个API的漏洞已经修复后,开发人员依然还在使用落后的版本,这些都会造成程序中有严重的安全漏洞。

为了解决这个问题,开发人员必须根据最新的关于Crypto API的安全规则来检查他们的应用程序。但是创建和更新一系列安全规则也是很具有挑战性的,随着安全专家发现的一些漏洞攻击,Crypto API也会随着时间而发生变化,过时的、不安全的密码学原语会有替代方案。

本篇文章的工作就是:基于Git上面代码的更新,学习Crypto API的正确使用方式,同时帮助生成和维护最新的Security rules。

在这里插入图片描述
代码的更改就是指程序在开发过程中,不同版本之间的代码上的变动。这在Git上是比较常见的,红色部分是旧版本的代码,绿色部分是新版本的代码,白色部分是没有变化的代码。

这篇文章就是根据Git上不同版本之间代码的变动,从中学习API的正确使用方式。它的假设是,如果一段代码更新了,它解决安全问题的可能性比引入安全问题的可能性要大。大多数的安全问题都是在最早的版本中就存在的,而不是在后续的版本更新中引入的。

它跟现有的一些直接从Big Code中学习知识的方法不同,如果依照统计学上的方法直接从Big code中学习API的正确使用方式,那么结果可能就是最多人用的API使用方式,就是正确的,这个在实际情况下是不一定的。所以这篇文章是基于代码的更改学习API的正确使用方式,它的好处是,即使大部分人都错误使用API,也可以产生一些有意义的结果。

尝试从代码更改中学习API的正确使用是很困难的,因为许多代码更改不会语义上影响API的使用方式。为了应对这一挑战,本文开发了一个适合于加密API的抽象概念,可以捕获相关的安全属性。我们的抽象概念捕获了代码更改如何影响密码API使用(例如,参数类型改变如何影响密码模式)的语义特征,这使得能够过滤无关或非语义的变化。


Approach

这是方法的整体流程,主要有四个步骤,分别对应图中的四个箭头。
在这里插入图片描述
首先从Git上收集一些开源项目,这些开源项目要包含多个版本的源代码,收集其中有代码更改的地方。
第二个步骤是利用程序抽象来获得有意义的语义信息。这是非常必要的,开发人员经常重构代码,以提高程序的性能或提供程序的可读性,而不是对API的类做语义上的改变。所以这里需要使用程序抽象来捕获API类上语义信息的修改,它捕获的信息叫Usage Changes。
第三个步骤是过滤掉一些Usage Changes,然后使用聚类算法,将相似的Changes聚在一起。
最后一步是人工分析这些聚好类的Changes,然后生成安全规则。
下面就分别说明这四个步骤。

(一)
第一个步骤就不多解释了,就是收集有多个版本的代码。因为这篇文章关注的是Java代码的Crypto API,所以它只收集跟关于Crypto API类的代码。

(二)
第二步是静态分析旧版本和新版本的代码,提取API不同用法的语义特征,并对其做抽象。

举一个例子,这是论文提供的例子。这是一个关于加密和解密的类,这个例子中有四处红色的部分。
在这里插入图片描述
这个例子中,关于Crypto API的类对象有两个,Cipher enc和Cipher dec。每一个API的类对象都将被为一个有向无环图,或者说是抽象为一棵树。这颗树里面包含的信息主要包括API类对象的类型、这个对象调用的方法,以及方法的参数。

右边这两幅图是对enc这个对象的抽象。图b是代码更新前的图,图c是代码更新之后的图。根节点是这是类对象的类型,这里enc的类型是Cipher,根节点的子节点是是这个对象调用的方法(getInstance是factory method,类似构造函数。)(解释图b和图c)

把程序中的每一个API的类对象都抽象成DAG,那么一个程序中会有很多个DAG。旧版本中的DAG记为A1-An,新版本的DAG记为B1-Bk。新旧版本的DAG还需要进行配对,这里不一定是按顺序的,A1不一定就是配对B1。因为n和k的数目不一定一样,代码更新以后变量的个数可能增加也可能减少,并且变量的名字也可能改变了,也没办法按照变量名来配对。所以使用Distance这个标准,将Distance最小的两张图配对在一起。
在这里插入图片描述
配对完成后,对比两张图就可以得知API类语义上的变化。因为我们只关心有变化的地方,所以把有变化的路径提取出来作为特征,F-是旧版本的DAG中的路径,F+是新版本的路径。
在这里插入图片描述

还是刚才那个例子,比较图b和图c,就可以发现API使用方式有三条路径是有变化的

(三)

第三步是过滤无关的,非语义变化的Usage Changes。然后,剩余的Usage Changes将被使用聚类算法聚类,以便人工检查、导出安全规则。

没有意义的代码更改不影响Crypto API的使用方式。那些代码重构或者只是简单地增删代码代码的情况应该过滤掉。这里有四种情况的Usage Changes应该被过滤掉。

在这里插入图片描述
经过过滤之后的Usage Changes将被使用聚类算法聚类。这里还是使用Distance来度量两个Usage changes的相似度。
Changes里面有路径,所以需要定义两个路径之间的距离。路径间的距离将被用于度量两个Usage Changes之间的距离。最后Changes之间距离近的就可以聚在一起。
这些公式大概就是这个意思。

在这里插入图片描述

(四)

最后一步就是生成rules。
在这里插入图片描述


Evaluation

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了18 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wcventure/article/details/104961201