fix(security): 页面文案 markdown 管线加标签/属性/协议净化(P0)
方案 10 §7.1 实锤漏洞:renderMarkdown() 用无参 createMarkdownProcessor,
默认 allowDangerousHtml + 无条件 rehype-raw,页面文案(about intro、开源页
叙述、README)的 raw HTML 直通 set:html——script/style/iframe/on* 全不剥。
- 新增 src/lib/rehype-content-sanitize.ts:标签白名单(不含 script/style/
iframe/object/form/link/meta/svg 等,危险标签整棵丢弃、未知标签解包保内容)
+ 属性白名单(a[href,title,rel]、img[src,alt,width,height,loading]、class/id)
+ 协议白名单(http/https/mailto + 站内相对 + 小图 data:)
- site-content.ts 插件链与文章管线同序:rehypeRaw → 内容净化 → class 白名单
→ 链接卡片(副作用为正:页面文案里的独立链接也会成 OG 卡片)
- 修两处自身实现坑(实测驱动):hast 的 class 属性名是 className(按 class
过滤会把合法排版类一起剃掉);属性白名单需统一小写比较(驼峰 key 比不到)
验证: 注入载荷实测(<script>/<iframe>/onclick/style="color:red"/
href="javascript:")全部剥离、合法 class="ink-2" 与文本保留;
构建 48 页 exit 0;E2E 37/37
Spec: none (安全修复,方案 P0)
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
859cac19a2
commit
b0a3881725
2 files changed
+108
-1
No files matched your search
+15
-1
@@ -121,7 +121,21 @@ export async function siteFavicon(): Promise<{ href: string; type: string }> {
|
||||
let mdProcessor: Promise<import('@astrojs/markdown-remark').MarkdownProcessor> | null = null;
|
||||
export async function renderMarkdown(md: string): Promise<string> {
|
||||
const { createMarkdownProcessor } = await import('@astrojs/markdown-remark');
|
||||
mdProcessor ??= createMarkdownProcessor();
|
||||
// 与 astro.config.mjs 的文章管线同序:raw → 内容净化(标签/属性/协议)→
|
||||
// class 白名单 → 链接卡片。此前这里 createMarkdownProcessor() 无参,页面
|
||||
// 文案的 raw HTML 直通 set:html(方案 10 §7.1 实锤漏洞:script/style/on* 不剥)。
|
||||
mdProcessor ??= (async () => {
|
||||
const [{ default: rehypeRaw }, { default: rehypeContentSanitize }, { default: rehypeClassWhitelist }, { default: rehypeLinkCards }] =
|
||||
await Promise.all([
|
||||
import('rehype-raw'),
|
||||
import('./rehype-content-sanitize'),
|
||||
import('./rehype-class-whitelist'),
|
||||
import('./rehype-link-cards'),
|
||||
]);
|
||||
return createMarkdownProcessor({
|
||||
rehypePlugins: [rehypeRaw, rehypeContentSanitize, rehypeClassWhitelist, rehypeLinkCards],
|
||||
});
|
||||
})();
|
||||
const { code } = await (await mdProcessor).render(md);
|
||||
return code;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user