Closed ernongxizhu closed 2 years ago
This is expected: that zip file contains source code that was compiled during the build process, and the dependency:sources goal only retrieves the source code of dependencies; it doesn't actually build the dependency (in this case, JFinal). The selected ma.getMethod()
is outside OFCMS's source code (it's the update
method of the JFinal class Db
), so we don't have source code for it in the database.
What you should do depends on what you want to achieve: you're looking for calls to Db.update
, and presumably you're only interested in calls made from within the OFCMS codebase? If so then you don't need the source of JFinal; you can remove the dependency:sources
goal, and select ma
(the call-site) rather than ma.getMethod()
to get working links to the place where OFCMS calls the JFinal method in question.
On the other hand if you do care about a third-party project's calls to update
, then you need to build (or download an existing) database for that project instead of OFCMS. The case where you need a single database for both projects occurs if you need to do things like track data-flow through third-party code: in that case you should place both project sources under a common root directory, make a build.sh
like (cd project1 && mvn clean install); (cd project2 && mvn clean install)
, then use that for your -c
build command. This will mean that CodeQL sees both projects get built and indexes the full source code of both.
创建一个
build.sh
like(cd project1 && mvn clean install); (cd project2 && mvn clean install)
If this method is used,The databases that generate ofcms and jfinal are not associated. Data flow is disconnected.
I want to define a source and a sink, but this sink is in the jar package of jfinal, which makes my data flow construction unsuccessful. Do you have any solutions?
The sink I want to define is this preparestatement (sql), which I cannot define in the jfinal package
Works for me:
Method:
/tmp/work
/tmp/work/ofcms-V1.1.2
/tmp/work/jfinal
, and git checkout jfinal-3.2
to match the version you're using/tmp/work/build.sh
:#!/bin/bash
(cd ofcms-V1.1.2 && mvn clean package -DskipTests)
(cd jfinal && mvn clean package -DskipTests)
cd /tmp/work && codeql database create -l java -c "./build.sh" db
/**
* @kind path-problem
*/
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow::PathGraph
class Config extends DataFlow::Configuration {
Config() {
this = "MyTestConfig"
}
override predicate isSource(DataFlow::Node n) {
exists(StringLiteral l |
n.asExpr() = l and
l.getLocation().getFile().getAbsolutePath().matches("%ofcms%")
)
}
override predicate isSink(DataFlow::Node n) {
n.asExpr().(Argument).getCall().getCallee().getName() = "prepareStatement"
}
}
from DataFlow::PathNode n1, DataFlow::PathNode n2, Config c
where c.hasFlowPath(n1, n2)
select n1, n1, n2, "path"
This is just an example that will find string constants in your code that eventually find their way to a prepareStatement
call.
Running this reveals the first result shows "system.user.delete"
from SysUserController.java
flowing to Db.update
then DbPro.update
then finally the prepareStatement
call you flagged.
Of course you would want to change the isSource
to track something more interesting than any string literal in OFCMS code, but I hope this helps you get started.
Works for me:
Method:
- Create a root directory
/tmp/work
- Unzip your gitee zip file to
/tmp/work/ofcms-V1.1.2
- Clone https://github.com/jfinal/jfinal to
/tmp/work/jfinal
, andgit checkout jfinal-3.2
to match the version you're using- Create
/tmp/work/build.sh
:#!/bin/bash (cd ofcms-V1.1.2 && mvn clean package -DskipTests) (cd jfinal && mvn clean package -DskipTests)
- Create a database:
cd /tmp/work && codeql database create -l java -c "./build.sh" db
- Query:
/** * @kind path-problem */ import java import semmle.code.java.dataflow.DataFlow import DataFlow::PathGraph class Config extends DataFlow::Configuration { Config() { this = "MyTestConfig" } override predicate isSource(DataFlow::Node n) { exists(StringLiteral l | n.asExpr() = l and l.getLocation().getFile().getAbsolutePath().matches("%ofcms%") ) } override predicate isSink(DataFlow::Node n) { n.asExpr().(Argument).getCall().getCallee().getName() = "prepareStatement" } } from DataFlow::PathNode n1, DataFlow::PathNode n2, Config c where c.hasFlowPath(n1, n2) select n1, n1, n2, "path"
This is just an example that will find string constants in your code that eventually find their way to a
prepareStatement
call.Running this reveals the first result shows
"system.user.delete"
fromSysUserController.java
flowing toDb.update
thenDbPro.update
then finally theprepareStatement
call you flagged.Of course you would want to change the
isSource
to track something more interesting than any string literal in OFCMS code, but I hope this helps you get started.
OHHHHHH!!!!! Thank you!
Some Java projects use third-party jar packages. My command to build the database is
codeql database create ofcms-ql --language=java --command="mvn clean install dependency:sources"
When querying, it is found that the jar package of the third party cannot be found And prompt:
Unable to handleMsgFromView: cannot open codeql-zip-archive://1-40/d%3A%5Ccodeql%5Cofcms-V1.1.2%5Cofcms-ql%5Csrc.zip/C_/Users/User/.m2/repository/com/jfinal/jfinal/3.2/jfinal-3.2.jar/com/jfinal/plugin/activerecord/Db.class. Detail: Unable to read file 'codeql-zip-archive://1-40/d:\codeql\ofcms-V1.1.2\ofcms-ql\src.zip/C_/Users/User/.m2/repository/com/jfinal/jfinal/3.2/jfinal-3.2.jar/com/jfinal/plugin/activerecord/Db.class' (Error: Unable to resolve nonexistent file 'codeql-zip-archive://1-40/d:\codeql\ofcms-V1.1.2\ofcms-ql\src.zip/C_/Users/User/.m2/repository/com/jfinal/jfinal/3.2/jfinal-3.2.jar/com/jfinal/plugin/activerecord/Db.class')
Code address: https://gitee.com/oufu/ofcms/repository/archive/V1.1.2?format=zip
Query statement: