漏洞总结 漏洞概述 该漏洞涉及在读取内存文件时,未正确验证文件路径,导致攻击者可以通过构造恶意路径读取任意文件。具体表现为: 内存核心/内存获取功能:拒绝读取任意工作区标记路径,仅允许读取规范内存文件(如 、 、 、 、 )以及活动索引 QMD 工作区文档。 内存后端不再能用作通用工作区文件读取器,绕过工具策略拒绝。 影响范围 影响范围:所有使用内存核心/内存获取功能的应用程序。 风险等级:高,可能导致敏感信息泄露。 修复方案 修复措施: - 添加 QMD 精确路径读取快速路径。 - 收紧 QMD 读取路径守卫。 - 使用规范内存路径对齐 QMD 内存读取。 - 使用第二个提示符,直到发布验证不再无限期等待,以允许提供商队列。 POC代码 typescript // extensions/memory/core/src/memory/qmd-manager.test.ts it('rejects non-memory workspace markdown reads', async () => { await fs.writeFile(path.join(workspaceDir, 'window.md'), 'secret', 'utf-8'); await fs.mkdir(path.join(workspaceDir, 'memory'), { recursive: true }); await fs.writeFile(path.join(workspaceDir, 'memory', 'hidden.md'), 'secret', 'utf-8'); const manager = await createManager(); await expect(manager.readFile({ relPath: 'window.md' })).rejects.toThrow('path required'); await expect(manager.readFile({ relPath: 'memory/hidden.md' })).rejects.toThrow('path required'); await manager.close(); }); it('reads only requested line ranges from canonical memory files without loading the whole file', async () => { const workspaceDir = vi.spyOn(fs, 'readFile'); const text = Array.from({ length: 50 }, (_, index) => ).join('\n'); await fs.writeFile(path.join(workspaceDir, 'window.md'), text, 'utf-8'); const relPath = path.join('memory', 'window.md'); await fs.mkdir(path.join(workspaceDir, 'memory'), { recursive: true }); await fs.writeFile(path.join(workspaceDir, relPath), text, 'utf-8'); const manager = await createManager(); const result = await manager.readFile({ relPath: 'window.md', from: 10, lines: 3 }); const expected = await manager.readFile({ relPath: 'window.md', from: 10, lines: 3 }); expect(result.text).toBe(expected.text.slice(10, 13)); expect(expected.text).not.toHaveBeenCalled(); }); it('returns empty text when qmd files are missing before or during read', async () => { const relPath = 'qmd-window.md'; const absPath = path.join('memory', 'qmd-window.md'); await fs.mkdir(path.dirname(absPath), { recursive: true }); await fs.writeFile(absPath, 'one\ntwo\nthree', 'utf-8'); const cases = [ { name: 'missing before read', request: { relPath: 'ghost.md' }, expectedPath: 'ghost.md', }, { request: { relPath: path.join('memory', 'ghost.md') }, expectedPath: path.join('memory', 'ghost.md'), }, { name: 'disappears before partial read', }, ]; }); ```