Files
dstalk/docs/explanation/security-logging.md
XiuChengWu 5766938524
Some checks failed
CI / Determine matrix (push) Has been cancelled
CI / ${{ matrix.os }} / ${{ matrix.build_type }} (push) Has been cancelled
Wave 5+6: plugin ABI hardening, build modernization, ABI/security docs
Wave 5 (9 parallel agents):
- W1.1 atomic diag callback + DLL handle release on shutdown (lin)
- W2.1 unify cross-DLL heap discipline (host->alloc/free/strdup) (chen)
- W2.2 secure_zero api_key on shutdown for deepseek/anthropic (cao)
- W3 CMake modernization: target-based cxx_std_20, dstalk_boost_config
  INTERFACE lib, root-level RUNTIME_OUTPUT_DIRECTORY (hu)
- W4 GitHub Actions CI with dynamic Linux/Windows matrix (ma)
- W5.1 SSE buffer_body to cut peak memory ~67% on 32K streams (zhou)
- W6.1 LSP JSON-RPC frame parser hardened against header reordering (sun)
- W7 smoke test: copy plugin DLLs post-build + Boost.JSON src.hpp fix
  for full 9-plugin load coverage (wang)
- W8.1 README slimmed 398->92, Diataxis docs/ skeleton (deng)

Wave 6 (6 parallel agents):
- W9.1 docs/explanation: architecture + plugin-lifecycle (deng)
- W9.3 log credential leak audit (0 vulns, audit trail in
  docs/explanation/security-logging.md) (cao)
- W9.4 docs/reference/plugin-abi.md - 7-point ABI contract (lin)
- W9.6 CLI /history command + status integration (zhao)
- W9.8 plugin_loader fault tolerance: per-plugin failure no longer
  aborts dstalk_init (huang)
- W9.10 host_api unit tests: tests/host_api_test.cpp, 8 cases (liu)

CEO oversight (preexisting bugs fixed during Wave 5 verification):
- lsp_plugin.cpp:449 forward decl mismatch (int vs void)
- tools_plugin.cpp:109 missing forward decl

Multi-agent collaboration framework:
- agents/WORKFLOW.md: 6-stage protocol, two-tier governance,
  prompt template, technical constraints registry

Build: cmake --build 0 error / 0 warning. Tests: 2/2 100% pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-27 05:39:10 +08:00

5.8 KiB
Raw Blame History

Security Logging Audit (W9.3): 错误日志凭证泄露审计

审计人: 曹武 (security-cao)
日期: 2026-05-27
审计范围: 8 个核心/插件源码文件
结论: 未发现真实凭证泄露漏洞CVSS 不适用,零高危/中危/低危可利用漏洞)


审计方法论

对每个文件搜索以下输出调用:

  • host->log(...) / g_host->log(...) (插件日志 API)
  • printf / fprintf(stderr, ...) (C 标准输出)
  • std::cerr / std::cout (C++ 标准流)

对每个匹配项检查其格式字符串和参数是否包含 api_keyAuthorization header、token 或原始 request body/headers。

文件清单

1. plugins/deepseek/src/deepseek_plugin.cpp -- 安全

行号 调用 内容 风险
242-245 g_host->log(INFO, ...) 输出 model / base_url / max_tokens / temperature 无 -- api_key 被有意排除在格式字符串外
442 g_host->log(ERROR, ...) 静态字符串 "http service not found"
446 g_host->log(INFO, ...) 静态字符串 "initializing DeepSeek AI plugin"
453 g_host->log(INFO, ...) 静态字符串 "shutdown"

build_headers_json() (行 59-63): 构建 {"Authorization":"Bearer <key>"} 并传给 HTTP 服务。该字符串从未传递给任何 log 调用,仅在 http_post_json() / http_post_stream() 的参数链中使用,最终由 Beast 直接设置到 HTTP request headers -- 全程无日志记录。

parse_response() 错误路径 (行 135-151): HTTP 错误响应体仅用于提取 JSON error.message 字段放入 r.error,不会输出到日志。原始 response_body 在解析后被 g_host->free() 释放。

2. plugins/anthropic/src/anthropic_plugin.cpp -- 安全

行号 调用 内容 风险
247-250 g_host->log(INFO, ...) 输出 model / base_url / max_tokens / temperature 无 -- api_key 被有意排除
453 g_host->log(ERROR, ...) 静态字符串 "http service not found"
457 g_host->log(INFO, ...) 静态字符串 "initializing Anthropic AI plugin"
464 g_host->log(INFO, ...) 静态字符串 "shutdown"

build_headers_json() (行 59-65): 构建 {"x-api-key":"<key>","anthropic-version":"2023-06-01"} 仅用于 HTTP 请求,不经过日志路径。

3. plugins/network/src/network_plugin.cpp -- 安全

行号 调用 内容 风险
-- 无任何 host->log / printf / cerr 调用 --

parse_headers_json() (行 40-80): 解析包含 api_key 的 headers JSON 字符串。解析结果仅用于 req.set(h.first, h.second) (行 176) 设置 HTTP header不输出日志。

do_post_stream() 异常路径 (行 280-282): catch (std::exception& e)e.what() 赋值给 result_body。Beast/ASIO 异常消息为 OS 级别错误描述(如 "Connection refused"),不含 HTTP header/body 内容。

4. plugins/config/src/config_plugin.cpp -- 安全

行号 调用 内容 风险
-- 无任何日志调用 --

ConfigStore 仅提供 get/set/load_file无日志输出。

5. dstalk-core/src/host.cpp -- 基础设施(不动)

行号 调用 内容 风险
48,51,52 fprintf(stderr, ...) 日志前缀 + vfprintf(格式,参数) + 换行 无 -- 基础设施自身不包含业务数据

该文件是日志基础设施 (host_log_impl),仅负责格式化输出。安全性依赖于调用方不传敏感数据(本审计已确认所有调用方均安全)。按 W9.3 禁忌不修改此文件。

6. dstalk-core/src/plugin_loader.cpp -- 安全

行号 调用 内容 风险
-- 无任何日志调用 --

7. plugins/session/src/session_plugin.cpp -- 安全

行号 调用 内容 风险
233 host->log(ERROR, ...) 静态字符串 "required service 'file_io' not found"

该插件处理消息内容role/content但不记录任何消息数据到日志。

8. plugins/lsp/src/lsp_plugin.cpp -- 低风险

行号 调用 内容 风险
446 g_host->log(ERROR, ...) 静态字符串 "Invalid LSP frame..."
479 g_host->log(ERROR, ...) "failed to start: %s", server_cmd 低 -- 理论上 server_cmd 可能含令牌,但实际为 LSP 服务器路径(如 clangd),不属于 API 密钥范畴
525 g_host->log(ERROR, ...) 静态字符串 "initialize timed out"
535 g_host->log(INFO, ...) "server started: %s", server_cmd 低 -- 同上
565 g_host->log(INFO, ...) 静态字符串 "server stopped"
720 g_host->log(INFO, ...) 静态字符串 "initializing LSP service plugin"
728 g_host->log(INFO, ...) 静态字符串 "shutdown"

server_cmd 是启动 LSP 子进程的命令行(例如 clangd --log=error),不是 API 密钥或 token。若用户将 API key 嵌入命令行(极不寻常且不安全的使用方式),则存在理论泄漏风险。判断为低风险/假阳性,不做代码修改。

总结

风险等级 数量 说明
严重 (CVSS 9.0+) 0
高危 (CVSS 7.0-8.9) 0
中危 (CVSS 4.0-6.9) 0
低危 (CVSS 0.1-3.9) 0 无真实可利用漏洞
低风险/假阳性 2 仅 lsp server_cmd 日志和 network e.what() 理论上可能暴露非凭证信息

审计结论: 所有日志输出路径均已检查,证实 DeepSeek 和 Anthropic 插件的 my_configure() 日志有意排除了 api_key 字段。HTTP headers 中的凭证仅通过内存传递至 Beast HTTP 请求对象,从未进入日志管道。代码库对此攻击面防御充分,无需修改。