fix(security): 属性级转义防注入 + 发布产物扩展名修复
- 链接/图片 href/src/alt/title 与代码块 language 属性改用属性级转义 (浏览器环境 escapeHTML 不转义双引号,存在属性注入面) - 修复 title 中反斜杠转义还原,引用链接 title 输出与行内一致 - 产物改用 .mjs/.cjs 扩展名(type:module 下 .js 被 Node 按 ESM 解析, require() 拿不到导出);exports 指向 dist 而非 src TS 源码 - 新增 .gitattributes 强制 LF,避免 Windows CRLF 污染 diff - 配套测试:title/URL/alt/language 注入防护
This commit is contained in:
@@ -1270,3 +1270,61 @@ describe('parseMarkdown - v0.2.2 自定义 token 渲染', () => {
|
||||
expect(html).toContain('<strong>Important!</strong>');
|
||||
});
|
||||
});
|
||||
|
||||
// ============ v0.2.5 链接 title 属性转义 ============
|
||||
|
||||
describe('parseMarkdown - v0.2.5 title 转义', () => {
|
||||
test('链接 title 中的引号被转义', () => {
|
||||
const html = parseMarkdown('[text](https://example.com "say \\"hi\\"")');
|
||||
expect(html).toContain('title="say "hi""');
|
||||
expect(html).not.toContain('title="say "hi""');
|
||||
});
|
||||
|
||||
test('链接 title 中的尖括号被转义', () => {
|
||||
const html = parseMarkdown('[text](https://example.com "a<b>c")');
|
||||
expect(html).toContain('title="a<b>c"');
|
||||
});
|
||||
|
||||
test('图片 title 被转义', () => {
|
||||
const html = parseMarkdown('');
|
||||
expect(html).toContain('title="x"y"');
|
||||
});
|
||||
|
||||
test('引用链接 title 被转义', () => {
|
||||
const html = parseMarkdown('[ref]: https://example.com "a\\"b"\n\n[text][ref]');
|
||||
expect(html).toContain('title="a"b"');
|
||||
});
|
||||
|
||||
test('引用图片 title 被转义', () => {
|
||||
const html = parseMarkdown('[img]: https://example.com/i.png "c<d>"\n\n![alt][img]');
|
||||
expect(html).toContain('title="c<d>"');
|
||||
});
|
||||
|
||||
test('链接 URL 中的引号不能注入属性', () => {
|
||||
const html = parseMarkdown('[x](https://example.com/"onclick="alert(1))');
|
||||
expect(html).not.toContain(' onclick=');
|
||||
expect(html).toContain('"onclick');
|
||||
});
|
||||
|
||||
test('图片 alt 中的引号不能注入属性', () => {
|
||||
const html = parseMarkdown('');
|
||||
expect(html).not.toContain(' onerror="');
|
||||
expect(html).toContain('"');
|
||||
});
|
||||
|
||||
test('代码块语言属性中的引号不能注入', () => {
|
||||
const html = parseMarkdown('```js" onclick="x\ncode\n```');
|
||||
expect(html).not.toContain('language-js');
|
||||
expect(html).not.toContain('onclick="x"');
|
||||
});
|
||||
|
||||
test('代码块 title 属性中的引号不能注入', () => {
|
||||
const html = parseMarkdown('```js title="a" onload="x"\ncode\n```');
|
||||
expect(html).not.toContain('onload');
|
||||
});
|
||||
|
||||
test('链接 title 中的反斜杠转义被还原', () => {
|
||||
const html = parseMarkdown('[text](https://example.com "say \\"hi\\"")');
|
||||
expect(html).toContain('title="say "hi""');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user