Gửi #1015959: DataLinkDC dinky v1.2.5 (unfixed through master 2026-09-18) Server-Side Request Forgery (SSRF)thông tin

tiêu đềDataLinkDC dinky v1.2.5 (unfixed through master 2026-09-18) Server-Side Request Forgery (SSRF)
Mô tảRequired fields (Submission Policy: vendor, product, affected versions, vulnerability class) - **Vendor**: DataLinkDC - **Product**: dinky (dinky-admin) - **Affected version(s)**: up to and including released tag v1.2.5, and unfixed at master as of 2026-09-18 (reviewed at released tag v1.2.5, commit ce7678eaa13722541f7d1eeda7ffbf8c9f753e20) - **Vulnerability class**: Server-Side Request Forgery with full response read-back (CWE-918) Preconditions - **Authentication / preconditions**: none — anyone who can reach the port can call it. No session, cookie or token header is required; the servlet mappings `/api/flink_web/proxy/*` and `/api/flink_web/*` are registered by default (`FlinkWebProxyServletConfiguration.java:36-43`) and no servlet-level authentication exists in the shipped configuration (H2 default profile, fresh install). - **CVSS**: assigned by VulDB during moderation; not claimed by the submitter. Optional vector hint only (not a claim), to speed the review: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N Title (one line) Unauthenticated SSRF in the Dinky Flink web UI proxy servlet via the caller-controlled _authority query parameter Description (technical, moderator-ready) Unauthenticated SSRF in the Dinky Flink web UI proxy servlet via the caller-controlled _authority query parameter Data flow: query `_authority` → `FlinkWebURITemplateProxyServlet.getNewTargetUri()` fills the template `http://{_authority}/#/job/running/{_jid}/overview` → smiley `ProxyServlet`/Apache HttpClient dial → upstream response body streamed back to the caller Affected interfaces | Interface | |---| | GET /api/flink_web/proxy?_authority=<host:port>&_jid=<anything> (also POST, and the sibling mapping /api/flink_web/*; query parameters `_authority`, `_jid`) | Primary route detail: ``` GET /api/flink_web/proxy?_authority=<host:port>&_jid=<anything> ``` Anonymous. No session, cookie or token header is required. An anonymous network caller can make dinky-admin open an HTTP connection to any host:port the server can reach and read the complete response body, because the Flink web UI proxy is registered as a raw servlet whose upstream authority is taken verbatim from the request query string. The route never reaches sa-token's login enforcement: that check is a Spring MVC `HandlerInterceptor` (`AppConfig.java:77-94`), and a `ServletRegistrationBean` servlet bypasses the Spring MVC dispatch chain entirely, while dinky-admin registers no servlet `Filter` at all. Root cause 1. `FlinkWebProxyServletConfiguration.servletRegistrationBean()` (`dinky-admin/src/main/java/org/dinky/configure/FlinkWebProxyServletConfiguration.java:36-43`) registers `FlinkWebURITemplateProxyServlet` (a smiley `ProxyServlet` subclass) as a raw servlet with the target template `http://{_authority}/#/job/running/{_jid}/overview` (TARGET_URI, `:33`) and mappings `/api/flink_web/proxy/*`, `/api/flink_web/*` (`:39`). 2. `FlinkWebURITemplateProxyServlet.getNewTargetUri()` (`dinky-admin/src/main/java/org/dinky/utils/FlinkWebURITemplateProxyServlet.java:137-153`) substitutes `{_authority}` and `{_jid}` in the template with values parsed from the **request query string** (`getParams`, `:155-169`) — the upstream authority is fully caller-controlled. 3. `service()` builds `new URI(newTargetUri)` and hands the request to the smiley `ProxyServlet` superclass, which dials the target via Apache HttpClient and streams the upstream **response body back to the caller**. 4. Missing guard: sa-token's login enforcement is registered as a Spring MVC interceptor on `/api/**` + `/openapi/**` (`dinky-admin/src/main/java/org/dinky/configure/AppConfig.java:77-94`), which never executes for a `ServletRegistrationBean` servlet, and no `Filter`/`FilterRegistrationBean`/`@WebFilter` exists anywhere in dinky-admin — so unlike the sibling `FlinkProxyController` (a `@SaCheckLogin`-annotated MVC controller under `/api/flink/**`), this proxy is reachable with no credentials. There is also no pinning of `_authority` to cluster addresses registered in dinky's own store and no scheme/host validation of the substituted value. Proof of concept Baseline: released tag v1.2.5 (commit `ce7678eaa13722541f7d1eeda7ffbf8c9f753e20`), official `dinky-release-1.20-1.2.5.tar.gz` dist, self-hosted instance on the reporter's own host, JDK 11, shipped-default H2 profile, HTTP on `127.0.0.1:18888`; harmless unique-marker canary listener returning `CV4-DINKY-CANARY-BODY-7731` bound to loopback-only `127.0.0.1:18903`. **1. Unauthenticated dial with response read-back (no cookie, no token header)** ```sh $ curl -s "http://127.0.0.1:18888/api/flink_web/proxy?_authority=127.0.0.1:18903&_jid=canary7731" -> CV4-DINKY-CANARY-BODY-7731 ``` **2. Application-originated connection (canary log, loopback-only listener)** ```sh $ cat canary.log 2026-09-16T23:54:36.116052 FROM ('127.0.0.1', 51822) REQ: GET / HTTP/1.1 ``` (The template `http://{_authority}/#/job/running/{_jid}/overview` dials `/` of the attacker-chosen authority `127.0.0.1:18903`; only the dinky JVM on the same host could reach the loopback-bound listener.) **3. Negative control (the login gate exists on the MVC sibling but not here)** — the same unauthenticated posture on the sibling controller route `/api/flink/**` is refused with `{"code":7,"msg":"Can Not Read Token"}`, proving sa-token enforcement is active for `/api/**` MVC handlers and simply never runs for this raw servlet. Impact See the interface and root-cause sections: an actor who satisfies the stated preconditions makes the server perform a request on a destination of the attacker's choosing and reads the full response body back, crossing the trust boundary described above. An unauthenticated attacker can aim dinky-admin's network position at any host/port reachable from the server process (internal admin panels, metadata services, cloud-instance localhost-only services) and read the full response — a complete internal-pivot/read primitive. Internal reachability was proven by construction: a canary listener bound to loopback-only `127.0.0.1:18903` (unreachable from off-host) was contacted by the dinky JVM and its body returned to the curl caller. References - Project repository: https://github.com/DataLinkDC/dinky - Security policy: `SECURITY.md` in that repository. Coordinated disclosure: vendor notified 2026-10-06 via GitHub Private Vulnerability Reporting (https://github.com/DataLinkDC/dinky/security/advisories/GHSA-wchp-mjj9-wxqh); not publicly disclosed; no CVE assigned. Duplicate check: public advisories and the issue tracker were searched before reporting.
Nguồn⚠️ https://github.com/DataLinkDC/dinky/security/advisories/GHSA-wchp-mjj9-wxqh
Người dùng
 lucasg2g (UID 84737)
Đệ trình06/10/2026 14:46 (cách đây 1 tháng)
Kiểm duyệt04/11/2026 15:17 (29 days later)
Trạng tháiđược chấp nhận
Mục VulDB431072 [DataLinkDC Dinky đến 1.2.5 flink_web Proxy Endpoint FlinkWebURITemplateProxyServlet.java FlinkWebURITemplateProxyServlet.getNewTargetUri _authority nâng cao đặc quyền]
điểm20

Might our Artificial Intelligence support you?

Check our Alexa App!