mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-17 04:01:13 +00:00
fix(webui): sanitize chat markdown rendering
This commit is contained in:
parent
7ba1d61e34
commit
35cfcb3be3
2 changed files with 29 additions and 6 deletions
|
|
@ -14,6 +14,7 @@ import { formatDuration } from "./time-utils.js";
|
|||
import { Scroller } from "./scroller.js";
|
||||
import { callJsExtensions } from "/js/extensions.js";
|
||||
import { addBlankTargetsToLinks } from "/js/html-links.js";
|
||||
import { sanitizeHtml } from "/js/safe-markdown.js";
|
||||
|
||||
// Delay before collapsing previous steps when a new step is added
|
||||
const STEP_COLLAPSE_DELAY = {
|
||||
|
|
@ -708,6 +709,10 @@ export function _drawMessage({
|
|||
processedContent = convertImgFilePaths(processedContent);
|
||||
processedContent = convertFilePaths(processedContent);
|
||||
processedContent = marked.parse(processedContent, { breaks: true });
|
||||
processedContent = sanitizeHtml(processedContent, {
|
||||
allowDataImages: true,
|
||||
allowLatex: latex,
|
||||
});
|
||||
processedContent = convertPathsToLinks(processedContent);
|
||||
processedContent = addBlankTargetsToLinks(processedContent);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,17 @@ const DOMPURIFY_CONFIG = Object.freeze({
|
|||
FORBID_TAGS: ["script", "iframe", "object", "embed", "svg", "math"],
|
||||
});
|
||||
|
||||
const DATA_IMAGE_URL_PATTERN =
|
||||
/^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,[a-z0-9+/=\s]+$/i;
|
||||
|
||||
function getDompurifyConfig(options = {}) {
|
||||
const config = { ...DOMPURIFY_CONFIG };
|
||||
if (options.allowLatex) {
|
||||
config.ADD_TAGS = ["latex"];
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
function parseGithubRepoContext(githubUrl) {
|
||||
if (!githubUrl || typeof githubUrl !== "string") return null;
|
||||
|
||||
|
|
@ -77,9 +88,16 @@ function isGithubRepoRoutePath(repoPath) {
|
|||
return GITHUB_REPO_ROUTE_PREFIXES.has(firstSegment);
|
||||
}
|
||||
|
||||
function isSafeUrlValue(value, attributeName) {
|
||||
function isSafeUrlValue(value, attributeName, options = {}) {
|
||||
const normalized = String(value || "").trim();
|
||||
if (!normalized) return true;
|
||||
if (
|
||||
options.allowDataImages &&
|
||||
attributeName === "src" &&
|
||||
DATA_IMAGE_URL_PATTERN.test(normalized)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
normalized.startsWith("#") ||
|
||||
normalized.startsWith("/") ||
|
||||
|
|
@ -108,14 +126,14 @@ function isSafeUrlValue(value, attributeName) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function stripUnsafeUrlAttributes(html) {
|
||||
function stripUnsafeUrlAttributes(html, options = {}) {
|
||||
const doc = new DOMParser().parseFromString(html, "text/html");
|
||||
|
||||
doc.querySelectorAll("[href], [src]").forEach((element) => {
|
||||
for (const attributeName of ["href", "src"]) {
|
||||
if (!element.hasAttribute(attributeName)) continue;
|
||||
const value = element.getAttribute(attributeName) || "";
|
||||
if (!isSafeUrlValue(value, attributeName)) {
|
||||
if (!isSafeUrlValue(value, attributeName, options)) {
|
||||
element.removeAttribute(attributeName);
|
||||
}
|
||||
}
|
||||
|
|
@ -124,10 +142,10 @@ function stripUnsafeUrlAttributes(html) {
|
|||
return doc.body.innerHTML;
|
||||
}
|
||||
|
||||
export function sanitizeHtml(html) {
|
||||
export function sanitizeHtml(html, options = {}) {
|
||||
if (!html || typeof html !== "string") return "";
|
||||
const sanitized = DOMPurify.sanitize(html, DOMPURIFY_CONFIG);
|
||||
return stripUnsafeUrlAttributes(sanitized);
|
||||
const sanitized = DOMPurify.sanitize(html, getDompurifyConfig(options));
|
||||
return stripUnsafeUrlAttributes(sanitized, options);
|
||||
}
|
||||
|
||||
export function rebaseGithubReadmeHtml(html, githubUrl, branch) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue