mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(chat): restrict generated-file link regex to http(s)/relative URLs
Follow-up to #447. The generated-file link extraction accepted any non-')' text before the path, so a paren-free javascript:/data: URL embedding /api/v1/files/generated/<id> could be captured and bound to an <a href>, enabling XSS on click. Adopt the scheme-restricted pattern already used by SegmentSupersedeDetector and the channel adapters, on both backend (ChatController) and frontend (useChat). Also replace the inline fully-qualified Pattern/Matcher with imports and drop an unused run-overview i18n key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3c6c765e51
commit
83660893a6
@ -37,6 +37,8 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -1733,8 +1735,8 @@ public class ChatController {
|
||||
|
||||
/** Markdown link pointing at a generated-file download URL. Used by the
|
||||
* StreamAccumulator to surface generated artifacts in the run-overview rail. */
|
||||
private static final java.util.regex.Pattern GENERATED_FILE_LINK_PATTERN =
|
||||
java.util.regex.Pattern.compile("\\[([^\\]]+)\\]\\(([^)]*?/api/v1/files/generated/[a-zA-Z0-9-]+)\\)");
|
||||
private static final Pattern GENERATED_FILE_LINK_PATTERN =
|
||||
Pattern.compile("\\[([^\\]]+)\\]\\(((?:https?://[^/\\s)\\]]+)?/api/v1/files/generated/[A-Za-z0-9-]+)\\)");
|
||||
|
||||
/**
|
||||
* 流式累积器 — 收集 StreamDelta 事件,持久化到 DB。
|
||||
@ -2044,7 +2046,7 @@ public class ChatController {
|
||||
* produce duplicate entries in the run-overview rail. */
|
||||
private void extractGeneratedFiles(String result, String toolName) {
|
||||
if (result == null || result.isBlank()) return;
|
||||
java.util.regex.Matcher m = GENERATED_FILE_LINK_PATTERN.matcher(result);
|
||||
Matcher m = GENERATED_FILE_LINK_PATTERN.matcher(result);
|
||||
while (m.find()) {
|
||||
String url = m.group(2);
|
||||
boolean dup = generatedFiles.stream()
|
||||
|
||||
@ -418,7 +418,7 @@ export function useChat(options: UseChatOptions): UseChatReturn {
|
||||
}
|
||||
|
||||
/** Markdown link pointing at a generated-file download URL. */
|
||||
const GENERATED_FILE_LINK_RE = /\[([^\]]+)\]\(([^)]*?\/api\/v1\/files\/generated\/[a-zA-Z0-9-]+)\)/g
|
||||
const GENERATED_FILE_LINK_RE = /\[([^\]]+)\]\(((?:https?:\/\/[^/\s)\]]+)?\/api\/v1\/files\/generated\/[A-Za-z0-9-]+)\)/g
|
||||
|
||||
/** Extract generated-file artifacts from a tool result string. */
|
||||
function extractGeneratedFiles(result: unknown, toolName: string): GeneratedFile[] {
|
||||
|
||||
@ -106,7 +106,6 @@ export default {
|
||||
plan: 'Plan Progress',
|
||||
subagents: 'Sub-agents',
|
||||
files: 'Generated Files',
|
||||
noFiles: 'No generated files yet',
|
||||
noPlan: 'No execution plan yet',
|
||||
noSubagents: 'No sub-agents yet',
|
||||
collapse: 'Collapse',
|
||||
|
||||
@ -106,7 +106,6 @@ export default {
|
||||
plan: '计划进度',
|
||||
subagents: '子 Agent',
|
||||
files: '生成文件',
|
||||
noFiles: '暂无生成文件',
|
||||
noPlan: '暂无执行计划',
|
||||
noSubagents: '暂无子 Agent',
|
||||
collapse: '收起总览',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user