[Java] - Limiting Flows Based on Patterns
- 主要語言
- CodeQL
- 星號
- 10.1k
- 分支
- 2.1k
- 平均合併
- 2 天 15 小時
- 30 天內合併 PR
- 141
描述
Hello, I am trying to restrict flows to only include those that have a source flow that is used as a query parameter.
For example, say authToken is a source,
```
String urlString = "http://auth.companyportal.com/auth?userId=" + userId + "&token=" + authToken;
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
```
However, my current query is picking up false positives where the source isn't used as a query parameter but somehow reaches the sink. Such as a dummy example like this
```
URL url = new URL(authToken);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
```
To address this I added a `isValidQueryParamFlow` predicate to my query that matches based on `".*\\?.*=.*"` however, this causes all of the expected detections to be removed. Even if I remove the regex, or relax the restrictions there still aren't any results. I know the rest of the query is operating as it should since I am getting the expected results without this check. So, I believe it is an issue with how I am performing this filtering.
Here is my full query
```
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
import SensitiveInfo.SensitiveInfo
import Barrier.Barrier
module Flow = TaintTracking::Global;
import Flow::PathGraph
/** A configuration for finding flows from sensitive information sources to URL constructions. */
module SensitiveInfoToUrlConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(SensitiveVariableExpr sve |
source.asExpr() = sve and
not sve.toString().toLowerCase().matches("%url%"))
}
predicate isSink(DataFlow::Node sink) {
// Direct use of URL with openConnection followed by setRequestMethod("GET")
exists(ConstructorCall urlConstructor, MethodCall openConnectionCall, MethodCall setRequestMethod |
urlConstructor.getConstructedType().hasQualifiedName("java.net", "URL") and
urlConstructor.getAnArgument() = sink.asExpr() and
openConnectionCall.getMethod().hasName("openConnection") and
openConnectionCall.getMethod().getDeclaringType().hasQualifiedName("java.net", "URL") and
DataFlow::localExprFlow(urlConstructor, openConnectionCall.getQualifier()) and
setRequestMethod.getMethod().hasName("setRequestMethod") and
((StringLiteral)setRequestMethod.getArgument(0)).getValue() = "GET" and
DataFlow::localExprFlow(openConnectionCall, setRequestMethod.getQualifier())
)
}
predicate isBarrier(DataFlow::Node node) {
Barrier::barrier(node)
}
}
predicate isValidQueryParamFlow(Flow::PathNode source, Flow::PathNode sink) {
exists(BinaryExpr be |
be.getOp() = "+" and
be.getLeftOperand().toString().matches(".*\\?.*=.*") and // Ensure there is a `=` after `?`
source.getNode().asExpr() = be.getRightOperand() and
sink.getNode().asExpr() = be
)
}
from Flow::PathNode source, Flow::PathNode sink
where Flow::flowPath(source, sink) and
isValidQueryParamFlow(source, sink)
select sink.getNode(), source, sink, "Sensitive information used in a URL constructed for a GET request."
```
Any help is appreciated, thank you,
貢獻指南
研究方向
先從 Java 範例和 isValidQueryParamFlow 謂詞開始,然後追蹤 Flow::flowPath 如何連接來源和接收端。使用查詢參數和直接 URL 的情況重現該查詢;完成標準是保留有效的查詢參數流,同時排除誤報情況。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- java
- 領域
- security
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 停滯
- 描述清晰度
- 基本清楚
- 新手友好度
- 25/100