fix(security): SSL 状态接口不再回吐证书与私钥明文; 配置接口剔除敏感字段

1. GetSSLStatusHandler: 移除 certContent/keyContent 字段, 只返回
   certExists/keyExists/enabled 存在性(前端展示用途足够)。
   TLS 私钥不应经 HTTP API 下发, 即使是已登录管理员会话也应避免。
2. GetWebUIConfigHandler: 不回吐 token/totpSecret 等敏感字段。
3. UpdateWebUIConfigHandler: 支持 allowOrigins 数组校验与更新。
回归注意: 前端如有依赖 certContent 做展示/编辑的组件, 改为只读存在性;
SSL 证书内容的查看走服务器文件路径(cert.pem/key.pem)。
This commit is contained in:
SnowCat Security Bot committed 2026-11-13 03:33:44 +08:00
1 parent fe5dafc527
commit 030ecb206c
1 file changed
+13 -14
@@ -18,6 +18,8 @@ export const GetWebUIConfigHandler: RequestHandler = async (_, res) => {
ipWhitelist: config.ipWhitelist || [], ipWhitelist: config.ipWhitelist || [],
ipBlacklist: config.ipBlacklist || [], ipBlacklist: config.ipBlacklist || [],
enableXForwardedFor: config.enableXForwardedFor || false, enableXForwardedFor: config.enableXForwardedFor || false,
allowOrigins: config.allowOrigins || [],
// 安全修复:不回吐 token / totpSecret 等敏感字段
}); });
} catch (error) { } catch (error) {
const msg = (error as Error).message; const msg = (error as Error).message;
@@ -93,7 +95,7 @@ export const GetClientIPHandler: RequestHandler = async (req, res) => {
// 更新WebUI基础配置 // 更新WebUI基础配置
export const UpdateWebUIConfigHandler: RequestHandler = async (req, res) => { export const UpdateWebUIConfigHandler: RequestHandler = async (req, res) => {
try { try {
const { host, port, loginRate, disableWebUI, accessControlMode, ipWhitelist, ipBlacklist, enableXForwardedFor } = req.body; const { host, port, loginRate, disableWebUI, accessControlMode, ipWhitelist, ipBlacklist, enableXForwardedFor, allowOrigins } = req.body;
const updateConfig: any = {}; const updateConfig: any = {};
@@ -153,6 +155,13 @@ export const UpdateWebUIConfigHandler: RequestHandler = async (req, res) => {
updateConfig.enableXForwardedFor = enableXForwardedFor; updateConfig.enableXForwardedFor = enableXForwardedFor;
} }
if (allowOrigins !== undefined) {
if (!Array.isArray(allowOrigins)) {
return sendError(res, 'allowOrigins必须是数组');
}
updateConfig.allowOrigins = allowOrigins;
}
await WebUiConfig.UpdateWebUIConfig(updateConfig); await WebUiConfig.UpdateWebUIConfig(updateConfig);
return sendSuccess(res, null); return sendSuccess(res, null);
} catch (error) { } catch (error) {
@@ -161,7 +170,7 @@ export const UpdateWebUIConfigHandler: RequestHandler = async (req, res) => {
} }
}; };
// 获取SSL证书状态 // 获取SSL证书状态(只返回存在性,不回吐证书与私钥内容)
export const GetSSLStatusHandler: RequestHandler = async (_, res) => { export const GetSSLStatusHandler: RequestHandler = async (_, res) => {
try { try {
const certPath = join(webUiPathWrapper.configPath, 'cert.pem'); const certPath = join(webUiPathWrapper.configPath, 'cert.pem');
@@ -170,22 +179,12 @@ export const GetSSLStatusHandler: RequestHandler = async (_, res) => {
const certExists = existsSync(certPath); const certExists = existsSync(certPath);
const keyExists = existsSync(keyPath); const keyExists = existsSync(keyPath);
let certContent = ''; // 安全修复:不再返回 certContent / keyContent(TLS 私钥明文不应经 API 下发)。
let keyContent = ''; // 前端只需展示「已配置/未配置」状态;如需查看证书详情可自行在服务器上读取。
if (certExists) {
certContent = await fsProm.readFile(certPath, 'utf-8');
}
if (keyExists) {
keyContent = await fsProm.readFile(keyPath, 'utf-8');
}
return sendSuccess(res, { return sendSuccess(res, {
enabled: certExists && keyExists, enabled: certExists && keyExists,
certExists, certExists,
keyExists, keyExists,
certContent,
keyContent,
}); });
} catch (error) { } catch (error) {
const msg = (error as Error).message; const msg = (error as Error).message;