tju-yxq opened a new issue, #1609: URL: https://github.com/apache/rocketmq-dashboard/issues/1609
## Bug Report ### Before Creating the Bug Report - [x] I found a bug, not just asking a question, which should be created in [GitHub Discussions](https://github.com/apache/rocketmq/discussions). - [x] I have searched the [GitHub Issues](https://github.com/apache/rocketmq/issues) and [GitHub Discussions](https://github.com/apache/rocketmq/discussions) of this repository and believe that this is not a duplicate. - [x] I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ. ### Runtime platform environment OS: Ubuntu 20.04 / Any OS running RocketMQ Studio ### RocketMQ version branch: rocketmq-studio Git commit id: bce4b10 ### JDK Version OpenJDK 21 ### Describe the Bug The SSRF guard in `SettingsService.testDataSource()` validates the initial data source URL against loopback, link-local, and any-local addresses. However, the `SimpleClientHttpRequestFactory` used by the `RestClient` **follows HTTP redirects by default**. An attacker can set up an external server that returns a `302 Found` redirect to `http://127.0.0.1:8080/actuator/env` (or any internal service), bypassing the SSRF guard entirely. ```java SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(DATA_SOURCE_TEST_CONNECT_TIMEOUT); requestFactory.setReadTimeout(DATA_SOURCE_TEST_READ_TIMEOUT); // No call to requestFactory.setFollowRedirects(false) — defaults to true this.restClient = restClientBuilder.requestFactory(requestFactory).build(); ``` ### Attack Scenario 1. Attacker sets up an external server at `http://evil.com/prometheus` that: - Returns a `302 Found` with `Location: http://127.0.0.1:8080/actuator/env` 2. Attacker enters `http://evil.com/prometheus` as a data source URL in Studio settings 3. The SSRF guard checks `evil.com` — passes (not loopback, not link-local) 4. The RestClient sends a GET request to `evil.com/prometheus` 5. `evil.com` responds with `302 Found` redirect to `127.0.0.1:8080/actuator/env` 6. The RestClient follows the redirect to `127.0.0.1:8080` — **bypassing the SSRF guard** 7. The response body from the internal service is returned to the attacker ### Impact - **Full SSRF bypass**: The existing SSRF guard (which blocks `localhost`, `127.x.x.x`, `::1`, link-local) is completely bypassed via redirect - **Access to internal services**: Spring Actuator endpoints, database admin panels, cloud metadata endpoints (if not already blocked at IP level) - **Information disclosure**: Error messages from internal services may leak internal architecture details ### Steps to Reproduce 1. Set up an external server that returns a `302` redirect to `http://127.0.0.1:8080/actuator/env` 2. In RocketMQ Studio, go to Settings > Data Sources > Test 3. Enter the external server URL 4. Observe: the test follows the redirect to localhost, bypassing the SSRF guard ### What Did You Expect to See? HTTP redirects should be disabled when testing data source URLs, so the SSRF guard cannot be bypassed. ### What Did You See Instead? Redirects are followed, allowing SSRF bypass. ### Additional Context **Affected file**: `server/src/main/java/org/apache/rocketmq/studio/settings/SettingsService.java`, constructor at approximately line 55. **Fix**: Disable redirect following on the `SimpleClientHttpRequestFactory`: ```java SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(DATA_SOURCE_TEST_CONNECT_TIMEOUT); requestFactory.setReadTimeout(DATA_SOURCE_TEST_READ_TIMEOUT); requestFactory.setFollowRedirects(false); // Prevent SSRF bypass via redirect ``` This is a one-line fix. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
