提出 #1035489: kekingcn kkFileView v5.0.2 (reviewed release commit `c4288f7e`, official-baseline jar `server/target/kkFileView-5.0.2.jar`); the `X-Base-Url` header precedence has been in place since 2021 and the same filter pair is still present on upstream `main` URL r情報

タイトルkekingcn kkFileView v5.0.2 (reviewed release commit `c4288f7e`, official-baseline jar `server/target/kkFileView-5.0.2.jar`); the `X-Base-Url` header precedence has been in place since 2021 and the same filter pair is still present on upstream `main` URL r
説明Unauthenticated open redirect via the attacker-controlled `X-Base-Url` header in kkFileView's trailing-slash normalization filter Vendor: kekingcn Affected versions: v5.0.2 (reviewed release commit `c4288f7e`, official-baseline jar `server/target/kkFileView-5.0.2.jar`); the `X-Base-Url` header precedence has been in place since 2021 and the same filter pair is still present on upstream `main` Vulnerability class: URL redirection to untrusted site (open redirect) (CWE-601) Preconditions: None. Any anonymous network caller can trigger it; no configuration change is needed, because the shipped default `baseUrl=default` makes `BaseUrlFilter` fall through to the request-supplied header, and these routes carry no authentication by default (access password disabled in the default configuration). Unauthenticated open redirect via the attacker-controlled `X-Base-Url` header in kkFileView's trailing-slash normalization filter Data flow: `HTTP request header X-Base-Url (any request whose path needs trailing-slash normalization, e.g. GET /index/)` → `BaseUrlFilter.getBaseUrl()` returns the header value unconditionally when present → `UrlCheckFilter` builds `redirectUrl = baseUrl + servletPath` → `sendRedirect(redirectUrl + "?" + queryString)` → `302 Location: <attacker URL><path>?<query>`, verbatim, with no scheme/host validation ### Affected interfaces | Interface | |---| | Any path ending in `/` or containing `//` (e.g. `GET /index/`) - `UrlCheckFilter` (mapped `/*`, order 30) emits `302 Location: <X-Base-Url value><path>?<query>` | Primary route detail: ``` GET /index/?poc=1 X-Base-Url: https://evil.example.com ``` Any anonymous network caller; the header is honored from the client directly: 1. `UrlCheckFilter` is registered on `/*` and triggers for trailing-slash (or `//`) paths regardless of authentication. 2. The shipped default `baseUrl=default` makes `BaseUrlFilter` fall through to the request-supplied `X-Base-Url` header, and no route on this path requires a login. ### Root cause The gap is a default-config, unauthenticated trust-boundary failure: a header designed for the operator's reverse proxy is honored from any client and lands unvalidated in `Location`. 1. `server/src/main/java/cn/keking/web/filter/BaseUrlFilter.java:43-45` - the request header wins unconditionally over the configured base URL: ```java final String urlInHeader = servletRequest.getHeader("X-Base-Url"); if (StringUtils.isNotEmpty(urlInHeader)) { baseUrl = urlInHeader; } ``` 2. `server/src/main/java/cn/keking/web/filter/UrlCheckFilter.java:30-47` - for a trailing-slash (or `//`) path the filter builds `redirectUrl = BaseUrlFilter.getBaseUrl() + servletPath` and emits the redirect: ```java ((HttpServletResponse) response).sendRedirect(redirectUrl + "?" + httpServletRequest.getQueryString()); ``` 3. No scheme/host validation is applied to `baseUrl` (no check against the deployment URL, no relative-path constraint): the header value is copied verbatim into the `Location` response header. `TrustHostFilter`/`TrustDirFilter` guard the URL-fetching and directory routes, not this redirect. Baseline: kkFileView v5.0.2 official-baseline jar, booted on `127.0.0.1:18120` with default `application.properties` (`baseUrl=default`, `trust.host=default`, access password disabled). **1. Positive - attacker header controls the redirect target:** ```http GET /index/?poc=1 HTTP/1.1 Host: 127.0.0.1:18120 X-Base-Url: https://evil.example.com Connection: close ``` Response (observed): ```http HTTP/1.1 302 Location: https://evil.example.com/index?poc=1 ``` (equivalent: `curl -s -D - -o /dev/null -H 'X-Base-Url: https://evil.example.com' 'http://127.0.0.1:18120/index/?poc=1'`) **2. Baseline behavior without the header** - `GET /index/` -> `HTTP/1.1 302` + `Location: http://127.0.0.1:18120/index?null` (self redirect: the trailing-slash normalization stays on the server's own origin). **3. Negative control** - `GET /index` (no trailing slash) -> `HTTP/1.1 200` (no redirect at all); `GET /index/` without the header -> `302` to the server's own base. The off-site redirect appears if and only if the attacker-controlled header is present. - **Vendor contact**: GitHub Private Vulnerability Reporting - kekingcn/kkFileView - **Status**: vendor notified 2026-10-06 through GitHub Private Vulnerability Reporting; private report https://github.com/kekingcn/kkFileView/security/advisories/GHSA-wrm9-r4fj-f8q5; not publicly disclosed; no CVE assigned - **Duplicate check**: public advisories (NVD/OSV/GitHub) and the project issue tracker were searched before reporting; please tell us if this duplicates something already tracked internally.
ソース⚠️ https://github.com/kekingcn/kkFileView
ユーザー
 lucasg2g (UID 84737)
送信2026年10月15日 07:33 (24 日 ago)
モデレーション2026年11月08日 15:13 (24 days later)
ステータス承諾済み
VulDBエントリ432888 [kekingcn kkFileView 迄 5.0.3 BaseUrlFilter.java BaseUrlFilter.getBaseUrl X-Base-Url Redirect]
ポイント20

Do you know our Splunk app?

Download it now for free!