btlqql opened a new pull request, #5334: URL: https://github.com/apache/rocketmq-dashboard/pull/5334
### Which Issue(s) This PR Fixes - Fixes #5165 ### Brief Description `UrlHostGuard.check` (`server/src/main/java/org/apache/rocketmq/studio/common/util/UrlHostGuard.java:73`) validated the scheme, the host and the resolved addresses but never inspected `URI.getUserInfo()`, so `http://prometheus:[email protected]:9090/metrics` passed validation, was persisted with the credential inside it, and was echoed back by the reader-visible data source list. The guard is the single choke point for data source URLs (`SettingsService.validateDataSourceUrl`), the LLM base URL (`SettingsService.validateLlmBaseUrl`) and webhook sends (`NotificationOutboxService`). The fix rejects any URL whose user-info is present and non-blank. The check runs after the cheap scheme/host checks and before host resolution, so it fails fast, and it names the dedicated credential field the caller should use instead. Clean URLs, private site-local hosts and loopback-for-local-LLM behaviour are unchanged. Note on scope: `LlmConfigService.isValidApiBase` (`ops/ai/**`) parses its own URI and asks only `UrlHostGuard.isAllowedHost`, so it is not covered by this change; it is outside the files this campaign assigned to me. Every path that goes through `UrlHostGuard.check` — data source save/update/test/query, LLM base URL through `SettingsService`, and webhook dispatch — is covered. ### How Did You Test This Change? New `UrlHostGuardUserInfoTest` covers the guard itself, and one test was added to `SettingsServiceTest` for the end-to-end save path. Before the fix (4 new tests fail, all 44 `SettingsServiceTest` tests report, the 43 pre-existing ones pass): ``` $ cd server && mvn -B -ntp test -Dtest=UrlHostGuardUserInfoTest,SettingsServiceTest [ERROR] Tests run: 4, Failures: 3, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.common.util.UrlHostGuardUserInfoTest Expecting code to raise a throwable. [ERROR] Tests run: 44, Failures: 1, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.settings.SettingsServiceTest Expecting code to raise a throwable. [ERROR] UrlHostGuardUserInfoTest.checkShouldRejectUserInfoWhenLoopbackIsAllowedTest:42 [ERROR] UrlHostGuardUserInfoTest.checkShouldRejectUserInfoWithPasswordTest:28 [ERROR] UrlHostGuardUserInfoTest.checkShouldRejectUserInfoWithoutPasswordTest:35 [ERROR] SettingsServiceTest.createDataSourceShouldRejectCredentialsEmbeddedInTheUrlTest:415 [ERROR] Tests run: 48, Failures: 4, Errors: 0, Skipped: 0 [INFO] BUILD FAILURE ``` After the fix: ``` $ cd server && mvn -B -ntp test -Dtest=UrlHostGuardUserInfoTest,SettingsServiceTest,UrlHostGuardTest,UrlHostGuardMulticastTest [INFO] You have 0 Checkstyle violations. [INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.common.util.UrlHostGuardUserInfoTest [INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.common.util.UrlHostGuardTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.common.util.UrlHostGuardMulticastTest [INFO] Tests run: 44, Failures: 0, Errors: 0, Skipped: 0 -- in org.apache.rocketmq.studio.settings.SettingsServiceTest [INFO] Tests run: 54, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS ``` The two `UrlHostGuard*` classes above are the pre-existing SSRF-guard tests (loopback, metadata, unique-local IPv6, multicast); they keep passing. ### Checklist - [x] One coherent change; unrelated modifications are not bundled in - [x] Commit subject follows Conventional Commits - [x] Tests added or updated for non-trivial changes - [x] New UI text has both Chinese and English entries under `web/src/i18n/` — not applicable, no UI text (the message is surfaced through the existing error path) - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit checks) — no new package or dependency edge - [x] New source files carry the ASF license header - [x] Documentation touched where behaviour changed (README / `docs/` / in-app help) — not applicable: the guard's class Javadoc already describes the accepted URL shape and the rejection message tells the caller what to do instead -- 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]
