Java SSRF Findings
- 主要言語
- CodeQL
- スター
- 10.1k
- フォーク
- 2.1k
- 平均マージ
- 2日 15時間
- マージ済み PR(30日)
- 141
説明
Hi Team,
Hope you're doing well!
Just adding this here as a question to check if anyone has any inputs or recommendations.
**Description of issue**
CWE-918 (SSRF) finding alert when input parameters are eventually appended to a URL used to make outbound calls to external systems in the source code.
However, the implementation includes multiple layers of mitigation, which I believe should prevent SSRF:
- The input string is validated via regex (alphanumeric + length check).
- A sanitization method strips any non-alphanumeric characters.-
- The base URL is sourced from a secure Spring Boot config (application.properties) using the @Value annotation.
- I’ve implemented an allow-list validation, ensuring the final URI starts with one of the expected base URLs.
- Despite these controls, CodeQL still flags the usage as SSRF in the RestTemplate.exchange() call.
Please refer to the code snippet below for reference:
**Code samples or links to source code**
**Controller(source)**
```
@RequestMapping(path = "{inputKey:^[a-zA-Z0-9]{8}$|^[a-zA-Z0-9]{10}$}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ApiResponses({ @ApiResponse(responseCode = "404", description = "Resource Not Found"),
@ApiResponse(responseCode = "200", description = "OK") })
public ResourceResponse getURLsByIdentifier(
@Parameter(description = "Enter inputKey.", name = "inputKey", required = true) @PathVariable("inputKey") String inputKey) {
### Source inputKey
return resourceService.getResourceUrls(sanitizeAlphanumeric(inputKey));
}
```
```
private String sanitizeAlphanumeric(String input) {
if (input == null) return "";
return input.replaceAll("[^a-zA-Z0-9]", "");
}
```
**Service Layer (Sink)**
```
//validated URL is being formed
URI configURI = UriComponentsBuilder.
fromUriString(baseUrl) //baseURl is pickup from Spring config using @Value annotation
.path(inputKey) // pased from controller
.queryParam("config", "true")
.build()
.toUri();
HttpEntity entity = new HttpEntity<>(getHeaders());
### Sink configURI
ResponseEntity> response = restTemplate.exchange(configURI, HttpMethod.GET, entity,
new ParameterizedTypeReference<>() {}); // Vunerbility reported here
//have implemented a URL validation mechanism by maintaining a map of all allowed base URLs and verifying
// whether the constructed configURI starts with one of the expected base URLs. However, this approach also did not help resolve the issue.
```
I’ve also verified that:
baseUrl is always from a known set of safe endpoints.
A custom check ensures the final URI starts with one of the allow-listed base URLs before making the request.
Appreciate any insights or suggestions. Happy to share more details if needed. Thanks in advance!
コントリビューションガイド
調査の方向性
Java Controller と Service Layer のスニペットから始め、path variable から URI の構築を経て RestTemplate.exchange() の sink に至るまで入力を追跡します。関連する CodeQL SSRF 解析が allow-listed base URLs と URI 検証をどのように扱うかを確認します。完了の条件は、これが再現可能な query の誤検知なのか、または triage に必要な不足している証拠を特定することです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- java, spring-boot
- 領域
- security
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 25/100