我正在尝试为Groovy创建静态分析。作为我的上司的POC,我只是试图解析简单的代码并检测SQL注入,这是最容易发现的。我在Python上做得很成功,这是我的主要语言,但我的公司主要使用Grails(在Groovy上)。
这是我到目前为止所做的:
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.ast.*
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.ast.CodeVisitorSupport
import org.codehaus.groovy.ast.builder.AstBuilder
public class SecurityCheck extends CodeVisitorSupport {
void visitBlockStatement(BlockStatement statement) {
println "NEW BLOCK STATEMENT:"
println statement.getText();
//keep walking...
statement.getStatements().each { ASTNode child ->
println "CHILD FOUND: "
println child.getText();
child.visit(this)
}
}
}
def code = new File('groovy_source.groovy').text // get the code from the source file
def AstBuilder astBuilder = new AstBuilder() // build an instance of the ast builder
def ast = astBuilder.buildFromString(CompilePhase.CONVERSION, code) // build from string when the compiler converts from tokens to AST
def SecurityCheck securityCheck = new SecurityCheck() // create an instance of our security check class
println ast
println ast[0]
ast[0].visit(securityCheck)
groovy_source.groovy文件非常简单,只包含一个极易发现漏洞的最小文件:
def post(id) {
query = "SELECT * FROM table WHERE id = " + id;
result = sql.execute query
return result;
}
我的理解是,当我继承CodeVisitorSupport时,这只会访问一个BlockStatement,然后,对于该语句中的每个语句,它将使用来自supper类的方法访问它。
然而,当我从BlockStatement打印文本时,它是一个空字符串,并且for each方法甚至都没有被调用(我认为这必须意味着AST找不到我的块语句的子代,即使函数最终也是如此)里面有陈述。
[org.codehaus.groovy.ast.stmt.BlockStatement@363a52f[]] // println ast
org.codehaus.groovy.ast.stmt.BlockStatement@363a52f[] // println ast[0]
NEW BLOCK STATEMENT:
{ } // println statement.getText()
这里的任何帮助都将非常感激。谢谢!
答案 0 :(得分:0)
我找到了答案。最后我并不那么努力,但可怕的文档并不容易。如果您要遍历树,则需要为构造函数提供false boolean作为第二个参数,如下所示:
def ast = astBuilder.buildFromString(CompilePhase.CONVERSION, false, code)
然后您可以按预期使用visit *方法。