zhaohai666 opened a new pull request, #1673:
URL: https://github.com/apache/rocketmq-dashboard/pull/1673

   # PR: fix(security): harden SSRF guards, default login and edge exposure
   
   **Branch:** `feature/studio-security-hardening`
   **Commit:** `814bf241` — pushed to `origin/feature/studio-security-hardening`
   **Base:** `apache:rocketmq-studio` @ `990ba092`
   **PR create link:** 
https://github.com/zhaohai666/rocketmq-dashboard/pull/new/feature/studio-security-hardening
   
   ## Summary
   
   Security hardening for the P0 items from the 2026-08-11 audit: SSRF guards 
are now
   shared and applied on every path that makes a server-side request to a
   caller-supplied URL, login is required by default and the auth gate fails 
closed,
   and the deployment no longer exposes the backend port or the full actuator 
surface.
   
   ## Changes
   
   ### Shared SSRF guard (`server/.../common/util/UrlHostGuard.java`, new)
   
   Rejects loopback, link-local (including the cloud-metadata range 
`169.254.169.254`)
   and any-local hosts. Unlike the old per-service check, unresolvable hosts are
   rejected (fail-closed) instead of being handed to the connection layer. 
Private
   site-local ranges stay allowed for on-premise Prometheus / internal LLM 
gateways.
   
   Applied on every path:
   
   - **Data source save** — `SettingsService.createDataSource/updateDataSource` 
now
     validate the URL when saving. Previously only the test path was guarded, 
so a
     data source pointing at `127.0.0.1` could be stored and later queried.
   - **Data source query** — 
`AbstractPrometheusCompatibleMetricsSource.queryRangeUri`
     validates the stored base URL on every request (defense in depth against 
direct
     DB edits).
   - **Data source test** — `SettingsService.isAllowedDataSourceHost` now 
delegates to
     the guard.
   - **LLM config** — `LlmConfigService.validate()` (used by both save and test)
     rejects link-local/metadata hosts while allowing loopback, so a local 
`ollama`
     gateway keeps working.
   
   ### Authentication
   
   - Default `studio.auth.login-required=true` in `application.yml`,
     `deploy/docker-compose.yml` and `deploy/deploy.sh`.
   - `AuthInterceptor.isLoginRequired()` fails closed when the settings store 
cannot
     be read (previously it defaulted to *no* login requirement).
   
   ### Deployment
   
   - `deploy/docker-compose.yml`: MySQL root password externalized to the
     `MYSQL_ROOT_PASSWORD` env var (compose-default `studio123` kept for
     out-of-the-box use); the healthcheck reads the password from the 
environment
     instead of hard-coding it in the command line.
   - `web/nginx.conf` + `deploy/nginx.conf`: only `/actuator/health` is proxied 
at
     the edge; the rest of `/actuator/` returns 404.
   - `deploy/deploy.sh`: the backend `8888` port is no longer published to the 
host
     (nginx already proxies `/api/` inside the podman network).
   
   ## Verification
   
   - `mvn compile` — BUILD SUCCESS (checkstyle clean).
   - `SettingsServiceTest` 31/31 (incl. two new SSRF rejection tests:
     create rejects loopback, update rejects metadata address),
     `LlmConfigServiceTest` 21/21, `AuthInterceptorTest` 16/16.
   
   ## Notes
   
   - Behavior change for existing deployments: login is now required by default;
     set `STUDIO_AUTH_LOGIN_REQUIRED=false` only when the deployment is 
intentionally
     unauthenticated (e.g. local development).
   


-- 
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]

Reply via email to