codeQL 笔记

codeQL

CodeQL是一种代码分析引擎,通过CodeQL可以根据已知的安全漏洞,在其他源代码中查找相似的安全问题。

谓词

定义方式类似于函数,和Java有点像的是在定义的时候需要指定是否有返回值,如果有返回值则需要以返回类型开头,如果没有返回值,则使用predicate开头

predicate southern(Person p) {
	p.getLocation() = "south"
}
int getAge(Person p) {
	result = 18
} 

递归

普通递归
Person ancestorOf(Person p) {
    result = parentOf(p) or
    result = parentOf(ancestorOf(p))
}

这种方式称为操作的传递闭包,再处理传递闭包时,+和*有特殊用法

  • parentOf+(p),这表示对变量p应用一次或多次谓词parentOf(),它等价于ancestorOf(p)
  • parentOf*(p),表示对变量p应用零次或多次谓词parentOf(),因此,它要么返回变量p的祖先,要么返回p本身
相互递归
int getAnEven() {
  result = 0
  or
  result <= 100 and result = getAnOdd() + 1
}
 
int getAnOdd() {
  result = getAnEven() + 1
}
 
select getAnEven()

闭包

传递闭包

使用的符号还是+和*

如果要将某个谓词应用一次或多次,可以在谓词名称后面加上”+“

假设我们定义了一个带有成员谓词getAParent()的类Person,那么p.getAparent()只会返回p的父辈。而传递闭包p.getAparent+()则会返回p的父辈、p的父辈的父辈,等等。

Person getAnAncestor() {
  result = this.getAParent()
  or
  result = this.getAParent().getAnAncestor()
}

自反传递闭包运算符*

和传递闭包的作用相似,不过使用*是将一个谓词用于自身零次或多次

比如p.getAparent*()的返回结果可能是p的父类或者p本身

显式定义为

Person getAnAncestor2() {
  result = this
  or
  result = this.getAParent().getAnAncestor2()
}

对于QL语言来说,可以用类表示一个逻辑属性:当一个值满足该属性时,它就是类的成员,这说明一个值可能是多个类的成员。

在codeQL中也有方法重写,就是重新定义父类中的成员谓词

class Child extends Person {
 
    /* the characteristic predicate */
    Child() { this.getAge() < 10 }
 
    /* a member predicate */
    override predicate isAllowedIn(string region) {
        region = this.getLocation()
    }
}
posted @ 2023-07-24 17:25  pr1s0n  阅读(37)  评论(0编辑  收藏  举报