mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-06-27 22:36:00 +00:00
🔒 Escape package name, version, keywords and funding https://github.com/siyuan-note/siyuan/security/advisories/GHSA-27qc-m5gf-jv5r (#17660)
This commit is contained in:
@@ -12,7 +12,7 @@ import {setStorageVal, writeText} from "../protyle/util/compatibility";
|
||||
import {hasClosestByAttribute, hasClosestByClassName} from "../protyle/util/hasClosest";
|
||||
import {Plugin} from "../plugin";
|
||||
import {App} from "../index";
|
||||
import {escapeAttr} from "../util/escape";
|
||||
import {escapeAttr, escapeHtml} from "../util/escape";
|
||||
import {uninstall} from "../plugin/uninstall";
|
||||
import {afterLoadPlugin, loadPlugin, loadPlugins} from "../plugin/loader";
|
||||
import {useShell} from "../util/pathName";
|
||||
@@ -235,7 +235,10 @@ export const bazaar = {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
new URL(funding);
|
||||
const url = new URL(funding);
|
||||
if (!["http:", "https:", "mailto:"].includes(url.protocol)) {
|
||||
throw new Error("not an allowed URL protocol");
|
||||
}
|
||||
return `<span class="fn__space--small"></span><a target="_blank" href="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></a>`;
|
||||
} catch (e) {
|
||||
return `<span class="fn__space--small"></span><span data-type="copy-funding" data-funding="${escapeAttr(funding)}" class="block__icon block__icon--show ariaLabel" data-position="north" aria-label="${window.siyuan.languages.sponsor} ${escapeAttr(funding)}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></span>`;
|
||||
@@ -272,7 +275,7 @@ export const bazaar = {
|
||||
</div>
|
||||
<div class="fn__flex-1 fn__flex-column">
|
||||
<div class="b3-card__info fn__flex-1">
|
||||
${item.preferredName}
|
||||
${escapeHtml(item.preferredName)}
|
||||
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">
|
||||
${item.preferredDesc || ""}
|
||||
</div>
|
||||
@@ -319,7 +322,7 @@ export const bazaar = {
|
||||
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
|
||||
<div class="fn__flex-1 fn__flex-column">
|
||||
<div class="b3-card__info b3-card__info--left fn__flex-1">
|
||||
${item.preferredName}
|
||||
${escapeHtml(item.preferredName)}
|
||||
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -428,7 +431,7 @@ export const bazaar = {
|
||||
<div class="b3-card__img"><img src="${item.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'"/></div>
|
||||
<div class="fn__flex-1 fn__flex-column">
|
||||
<div class="b3-card__info b3-card__info--left fn__flex-1">
|
||||
${item.preferredName}
|
||||
${escapeHtml(item.preferredName)}
|
||||
<div class="b3-card__desc" title="${escapeAttr(item.preferredDesc) || ""}">${item.preferredDesc || ""}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -521,11 +524,11 @@ type="checkbox">
|
||||
</div>
|
||||
<img class="item__img" src="${data.iconURL}" loading="lazy" onerror="this.src='/stage/images/icon.png'">
|
||||
<div>
|
||||
<a href="${data.repoURL}" target="_blank" class="item__title" title="GitHub Repo">${data.preferredName}</a>
|
||||
<a href="${data.repoURL}" target="_blank" class="item__title" title="GitHub Repo">${escapeHtml(data.preferredName)}</a>
|
||||
</div>
|
||||
<div class="fn__hr"></div>
|
||||
<div>
|
||||
<a href="${data.repoURL}" target="_blank" class="ft__on-surface ft__smaller" title="GitHub Repo">${data.name}</a>
|
||||
<a href="${data.repoURL}" target="_blank" class="ft__on-surface ft__smaller" title="GitHub Repo">${escapeHtml(data.name)}</a>
|
||||
</div>
|
||||
<div class="block__icons">
|
||||
<span class="fn__flex-1"></span>
|
||||
@@ -539,7 +542,7 @@ type="checkbox">
|
||||
</div>
|
||||
<div class="fn__hr--b"></div>
|
||||
<div class="fn__hr--b"></div>
|
||||
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${window.siyuan.languages.currentVer}<br>v${data.version}</div>
|
||||
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${window.siyuan.languages.currentVer}<br>v${escapeHtml(data.version)}</div>
|
||||
<div class="fn__hr"></div>
|
||||
<div class="ft__on-surface ft__smaller" style="line-height: 20px;">${downloaded ? window.siyuan.languages.installDate : window.siyuan.languages.releaseDate}<br>${downloaded ? data.hInstallDate : data.hUpdated}</div>
|
||||
<div class="fn__hr${downloaded ? " fn__none" : ""}"></div>
|
||||
|
||||
@@ -131,18 +131,31 @@ func ParsePackageJSON(filePath string) (ret *Package, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// sanitizePackageDisplayStrings 对集市包直接显示的信息做 HTML 转义,避免 XSS。
|
||||
// sanitizePackageDisplayStrings 对集市包可能直接显示的信息做 HTML 转义,避免 XSS。
|
||||
func sanitizePackageDisplayStrings(pkg *Package) {
|
||||
if pkg == nil {
|
||||
return
|
||||
}
|
||||
pkg.Name = html.EscapeString(pkg.Name)
|
||||
pkg.Author = html.EscapeString(pkg.Author)
|
||||
pkg.Version = html.EscapeString(pkg.Version)
|
||||
for k, v := range pkg.DisplayName {
|
||||
pkg.DisplayName[k] = html.EscapeString(v)
|
||||
}
|
||||
for k, v := range pkg.Description {
|
||||
pkg.Description[k] = html.EscapeString(v)
|
||||
}
|
||||
if pkg.Funding != nil {
|
||||
pkg.Funding.OpenCollective = html.EscapeString(pkg.Funding.OpenCollective)
|
||||
pkg.Funding.Patreon = html.EscapeString(pkg.Funding.Patreon)
|
||||
pkg.Funding.GitHub = html.EscapeString(pkg.Funding.GitHub)
|
||||
for i, v := range pkg.Funding.Custom {
|
||||
pkg.Funding.Custom[i] = html.EscapeString(v)
|
||||
}
|
||||
}
|
||||
for i, kw := range pkg.Keywords {
|
||||
pkg.Keywords[i] = html.EscapeString(kw)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPreferredLocaleString 从 LocaleStrings 中按当前语种取值,无则回退 default、en_US,再回退 fallback。
|
||||
@@ -177,7 +190,11 @@ func getPreferredFunding(funding *Funding) string {
|
||||
return v
|
||||
}
|
||||
if 0 < len(funding.Custom) {
|
||||
return funding.Custom[0]
|
||||
v := funding.Custom[0]
|
||||
if strings.HasPrefix(v, "https://") || strings.HasPrefix(v, "http://") || strings.HasPrefix(v, "mailto:") {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user