From a806f7b707729317dafb499b63e912e76b751887 Mon Sep 17 00:00:00 2001 From: Yingfeng Date: Mon, 2 Mar 2026 19:11:52 +0800 Subject: [PATCH] Potential fix for code scanning alert no. 71: Incomplete URL substring sanitization (#13318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Potential fix for [https://github.com/infiniflow/ragflow/security/code-scanning/71](https://github.com/infiniflow/ragflow/security/code-scanning/71) In general, instead of using `String.prototype.includes` on the entire URL string, parse the URL and make decisions based on its `host` (or `hostname`) field. This avoids cases where the trusted domain appears in the path, query, or as part of a different hostname. Here, `payload.source_fid` is set to `'siliconflow_intl'` if `postBody.base_url` “contains” `api.siliconflow.com`. To keep behavior for correct inputs but close the hole, we should: 1. Safely parse `postBody.base_url` using the standard `URL` class. 2. Extract the hostname (`url.hostname`). 3. Compare it appropriately: - If we only want the exact host `api.siliconflow.com`, use strict equality. - If international endpoints may include subdomains like `foo.api.siliconflow.com`, allow those via suffix check on the hostname. 4. Fall back to `LLMFactory.SILICONFLOW` if parsing fails or the host does not match. Concretely, in `web/src/pages/user-setting/setting-model/hooks.tsx`, in the `onApiKeySavingOk` callback where `payload.source_fid` is set, replace the `toLowerCase().includes('api.siliconflow.com')` logic with a small block that: - Initializes a local `let sourceFid = LLMFactory.SILICONFLOW;` - If `postBody.base_url` is present, attempts `new URL(postBody.base_url)` inside a `try/catch`, lowercases `url.hostname`, and checks whether it equals `api.siliconflow.com` or ends with `.api.siliconflow.com`. - Assigns `payload.source_fid = sourceFid`. No new external dependencies are required; `URL` is available in modern browsers and Node, and TypeScript understands it. _Suggested fixes powered by Copilot Autofix. Review carefully before merging._ Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .../user-setting/setting-model/hooks.tsx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/web/src/pages/user-setting/setting-model/hooks.tsx b/web/src/pages/user-setting/setting-model/hooks.tsx index 72bd08704..fe233e057 100644 --- a/web/src/pages/user-setting/setting-model/hooks.tsx +++ b/web/src/pages/user-setting/setting-model/hooks.tsx @@ -49,11 +49,23 @@ export const useSubmitApiKey = () => { verify: isVerify, }; if (savingParams.llm_factory === LLMFactory.SILICONFLOW) { - payload.source_fid = (postBody.base_url || '') - .toLowerCase() - .includes('api.siliconflow.com') - ? 'siliconflow_intl' - : LLMFactory.SILICONFLOW; + let sourceFid = LLMFactory.SILICONFLOW; + const baseUrl = postBody.base_url; + if (baseUrl) { + try { + const parsed = new URL(baseUrl); + const host = parsed.hostname.toLowerCase(); + if ( + host === 'api.siliconflow.com' || + host.endsWith('.api.siliconflow.com') + ) { + sourceFid = 'siliconflow_intl'; + } + } catch { + // ignore invalid URL and keep default sourceFid + } + } + payload.source_fid = sourceFid; } const ret = await saveApiKey(payload);