github / github/codeql

[Java] - Limiting Flows Based on Patterns

未關閉
#18,050 11 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
question
主要語言
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

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。