${typeMark}
@@ -877,7 +950,7 @@
${pillLabel}
-
${escapeHtml(l.id)}
+ ${escapeHtml(l.id)}
${l.status === 'stopped'
- ? `▶ ${escapeHtml(c2t('c2.listeners.start'))} `
- : `⏹ ${escapeHtml(c2t('c2.listeners.stop'))} `
+ ? `▶ ${escapeHtml(c2t('c2.listeners.start'))} `
+ : `⏹ ${escapeHtml(c2t('c2.listeners.stop'))} `
}
- ${escapeHtml(c2t('c2.listeners.edit'))}
- ${escapeHtml(c2t('c2.listeners.delete'))}
+ ${escapeHtml(c2t('c2.listeners.edit'))}
+ ${escapeHtml(c2t('c2.listeners.delete'))}
-
+
@@ -1003,7 +1076,7 @@
-
+
- ${escapeHtml(currentLine)}
@@ -2778,16 +2854,16 @@
- ${escapeHtml(sizeLabel)}
+ ${escapeHtml(sizeLabel)}
${escapeHtml(entry.mode)}
- ${entry.isDir
- ? `${escapeHtml(c2t('c2.files.open'))} `
- : `${escapeHtml(c2t('c2.files.download'))} `
- }
+ ${escapeHtml(c2t(entry.isDir ? 'c2.files.open' : 'c2.files.download'))}
`;
@@ -3366,7 +3442,7 @@
${escapeHtml(c2t('c2.tasks.sessionTaskHistory'))}
0
-
- ${escapeHtml(entry.name)}
+ ${escapeHtml(entry.name)}
@@ -3383,7 +3459,7 @@
${escapeHtml(c2t('c2.tasks.sessionTaskHistory'))}
${countLabel}
-
${tasks.map(t => {
@@ -3395,11 +3471,11 @@
const isPending = status === 'queued' || status === 'sent' || status === 'running';
const timeStr = formatTime(t.completedAt || t.createdAt);
return `
-
+
-
+
${escapeHtml(t.taskType || '-')}
-
+
-
+
@@ -3461,10 +3537,11 @@
- ${C2.tasks.map(t => {
- const rawId = t.id || '';
- const tid = escapeHtml(rawId);
- const status = String(t.status || '');
+ ${C2.tasks.map(t => {
+ const rawId = t.id || '';
+ const tid = escapeHtml(rawId);
+ const tidAttr = escapeAttr(rawId);
+ const status = String(t.status || '');
const rowStatus = escapeHtml(status || 'queued');
const typeCat = taskTypeCategory(t.taskType);
const sessionFull = t.sessionId ? String(t.sessionId) : '';
@@ -3478,25 +3555,25 @@
const cmdEsc = escapeHtml(cmd);
const canCancel = status === 'queued' || status === 'sent';
return `
-
-
+
+
-
+
${escapeHtml(formatTime(t.createdAt))}
${escapeHtml(taskStatusLabel(status))}
${escapeHtml(t.taskType || '-')}
- ${cmdEsc || dash}
- ${sessionShort || dash}
- ${taskShort || dash}
+ ${cmdEsc || dash}
+ ${sessionShort || dash}
+ ${taskShort || dash}
${formatDuration(t.durationMs)}
-
+
`;
@@ -3717,7 +3794,7 @@
C2.renderPayloadPage = function() {
const optionsHtml = C2.listeners.length > 0
? C2.listeners.map(l =>
- ``
+ ``
).join('')
: '';
@@ -3734,7 +3811,7 @@
let buildOptionsHtml;
if (listeners.length > 0) {
buildOptionsHtml = listeners.map(l =>
- ``
+ ``
).join('');
} else {
buildOptionsHtml = '';
@@ -3831,7 +3908,7 @@
${escapeHtml(c2t('c2.payloads.download'))}
`;
@@ -4213,7 +4290,7 @@
-
+
@@ -4227,8 +4304,10 @@
- ${C2.events.map(e => {
- const eid = escapeHtml(e.id || '');
+ ${C2.events.map(e => {
+ const rawId = e.id || '';
+ const eid = escapeHtml(rawId);
+ const eidAttr = escapeAttr(rawId);
const levelCls = eventLevelBadgeClass(e.level);
const catCls = eventCategoryBadgeClass(e.category);
const sessionShort = e.sessionId ? escapeHtml(String(e.sessionId).substring(0, 10)) + (String(e.sessionId).length > 10 ? '\u2026' : '') : '';
@@ -4236,20 +4315,20 @@
const msg = escapeHtml(e.message || '');
const rowLevel = escapeHtml(e.level || 'info');
return `
-
-
+
+
-
+
${escapeHtml(formatTime(e.createdAt))}
${escapeHtml(eventLevelLabel(e.level))}
${escapeHtml(eventCategoryLabel(e.category))}
-
- ${sessionShort || dash}
- ${taskShort || dash}
-
- ${deleteIcon}
+
+ ${sessionShort || dash}
+ ${taskShort || dash}
+
+ ${deleteIcon}
`;
}).join('')}
@@ -4364,7 +4443,7 @@
${escapeHtml(c2t('common.delete'))}
+ ${escapeHtml(c2t('common.delete'))}
${escapeHtml(c2t('c2.profiles.profileNameLabel'))}
-
+
${escapeHtml(c2t('c2.profiles.userAgent'))}
diff --git a/web/static/js/chat-files.js b/web/static/js/chat-files.js
index c5fe3858..b9d29956 100644
--- a/web/static/js/chat-files.js
+++ b/web/static/js/chat-files.js
@@ -13,6 +13,10 @@ let chatFilesPage = 1;
let chatFilesPageSize = 20;
let chatFilesSearchDebounceTimer = null;
+function chatFilesEscapeAttr(text) {
+ return escapeHtml(text).replace(/"/g, '"').replace(/'/g, ''');
+}
+
const CHAT_FILES_GROUP_STORAGE_KEY = 'csai_chat_files_group_by';
const CHAT_FILES_BROWSE_PATH_KEY = 'csai_chat_files_browse_path';
const CHAT_FILES_PAGE_SIZE_STORAGE_KEY = 'csai_chat_files_page_size';
@@ -1077,7 +1081,7 @@ function renderChatFilesTable() {
${escapeHtml(f.date || '—')}
${subCellInner}
- ${nameEsc}${sourceBadge}
+ ${nameEsc}${sourceBadge}
${formatChatFileBytes(f.size || 0)}
${escapeHtml(dt)}
@@ -1178,7 +1182,7 @@ function renderChatFilesTable() {
? `${svgTrash} `
: '';
return `
-
+
${svgFolder}${escapeHtml(folderDisplay.text)}
—
@@ -1228,7 +1232,7 @@ function renderChatFilesTable() {
const menuHtml = menuParts.join('');
return `
-
+
${svgFile}${nameEsc}${sourceBadge}
${formatChatFileBytes(f.size || 0)}
diff --git a/web/static/js/chat.js b/web/static/js/chat.js
index 37bbd4ba..12da72f1 100644
--- a/web/static/js/chat.js
+++ b/web/static/js/chat.js
@@ -8495,7 +8495,14 @@ function createConversationListItemWithMenu(conversation, isPinned) {
if (group) {
const groupTag = document.createElement('div');
groupTag.className = 'conversation-group-tag';
- groupTag.innerHTML = `${group.name}`;
+ const groupTagIcon = document.createElement('span');
+ groupTagIcon.className = 'group-tag-icon';
+ groupTagIcon.textContent = group.icon || '📁';
+ const groupTagName = document.createElement('span');
+ groupTagName.className = 'group-tag-name';
+ groupTagName.textContent = group.name;
+ groupTag.appendChild(groupTagIcon);
+ groupTag.appendChild(groupTagName);
groupTag.title = `分组: ${group.name}`;
contentWrapper.appendChild(groupTag);
}
@@ -9044,12 +9051,23 @@ async function showMoveToGroupSubmenu() {
const item = document.createElement('div');
item.className = 'context-submenu-item';
- item.innerHTML = `
-
- ${group.name}
- `;
+ const folderIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ folderIcon.setAttribute('width', '16');
+ folderIcon.setAttribute('height', '16');
+ folderIcon.setAttribute('viewBox', '0 0 24 24');
+ folderIcon.setAttribute('fill', 'none');
+ folderIcon.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+ const folderPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
+ folderPath.setAttribute('d', 'M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z');
+ folderPath.setAttribute('stroke', 'currentColor');
+ folderPath.setAttribute('stroke-width', '2');
+ folderPath.setAttribute('stroke-linecap', 'round');
+ folderPath.setAttribute('stroke-linejoin', 'round');
+ folderIcon.appendChild(folderPath);
+ const label = document.createElement('span');
+ label.textContent = group.name;
+ item.appendChild(folderIcon);
+ item.appendChild(label);
item.onclick = () => {
moveConversationToGroup(contextMenuConversationId, group.id);
};
diff --git a/web/static/js/info-collect.js b/web/static/js/info-collect.js
index 490fd0d9..c61d61ba 100644
--- a/web/static/js/info-collect.js
+++ b/web/static/js/info-collect.js
@@ -166,6 +166,10 @@ if (typeof escapeHtml === 'undefined') {
}
}
+function escapeAttr(text) {
+ return escapeHtml(text).replace(/"/g, '"').replace(/'/g, ''');
+}
+
function getFofaFormElements() {
return {
query: document.getElementById('fofa-query'),
@@ -1115,11 +1119,11 @@ function renderFofaResults(payload) {
if (f === 'host') {
const href = normalizeHttpLink(text);
if (href) {
- const safeHref = escapeHtml(href);
- return `${escapeHtml(text)} `;
+ const safeHref = escapeAttr(href);
+ return `${escapeHtml(text)} `;
}
}
- return `${escapeHtml(text)} `;
+ return `${escapeHtml(text)} `;
}).join('');
const actionHtml = `
diff --git a/web/static/js/knowledge.js b/web/static/js/knowledge.js
index e32bb7c2..996c58b1 100644
--- a/web/static/js/knowledge.js
+++ b/web/static/js/knowledge.js
@@ -194,7 +194,7 @@ function renderKnowledgeItemsByCategories(categoriesWithItems) {
const categoryCount = categoryData.itemCount || categoryItems.length;
html += `
-
${cmdShort
? `
`;
}).join('')}
@@ -3446,7 +3522,7 @@
${escapeHtml(cmdShort)}`
: `—`}
@@ -3408,8 +3484,8 @@
${canCancel
- ? `${escapeHtml(c2t('c2.tasks.cancelBtn'))} `
- : ''}
- ${deleteIcon}
+ ? `${escapeHtml(c2t('c2.tasks.cancelBtn'))} `
+ : ''}
+ ${deleteIcon}
✓ ${escapeHtml(c2t('c2.payloads.buildSuccessTitle'))}
${escapeHtml(c2t('c2.payloads.buildMetaOsArch', { os: data.payload?.os, arch: data.payload?.arch }))}
${escapeHtml(c2t('c2.payloads.buildSize', { bytes: data.payload?.size_bytes }))}
- ${escapeHtml(p.name)}
-UA: ${escapeHtml(p.userAgent || defVal)}
@@ -4389,7 +4468,7 @@
${convEsc}
+
${escapeHtml(category)}
@@ -245,7 +245,7 @@ function renderKnowledgeItems(items) { const categoryCount = categoryItems.length; html += ` -
+
${escapeHtml(category)}
@@ -347,10 +347,10 @@ function renderKnowledgeItemCard(item) { } return ` -
+
-