marked とは?
markedは Node.js 向けの高速な Markdown パーサで、Markdown を HTML に変換する用途に非常によく使われるライブラリです。
npm install marked
const { marked } = require('marked');
const txt = "world";
const markdown = `# Hello, *${txt}*!
<h1>header</h1>
`;
const html = marked(markdown);
console.log(html);
サニタイズする
dompurify と jsdom をインストールするには、以下のコマンドを実行します。
npm install dompurify jsdom
サンプルコード
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
const clean = DOMPurify.sanitize('<script>alert(1)</script><b>OK</b>');
console.log(clean); // → <b>OK</b>
code タグの中をエスケープする
const { marked } = require('marked');
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
// HTMLをエスケープする関数
function escapeHTML(html) {
return String(html)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
}
// marked の拡張機能で code トークンのみ HTML エスケープ
marked.use({
extensions: [{
name: 'escapeCodeBlockHTML',
renderer: {
code(code, infostring) {
const langClass = infostring ? ` class="language-${infostring}"` : '';
return `<pre><code${langClass}>${escapeHTML(code)}</code></pre>`;
}
}
}]
});
// 入力Markdown
const markdown = `
# header
<p><b class="hoge">HTML OK</b></p>
\`\`\`html
<script>alert(1)</script>
<b>タグ</b>
\`\`\`
`;
const dirtyHtml = marked(markdown);
// サニタイズ(scriptなどは除外される)
const clean = DOMPurify.sanitize(dirtyHtml, {
ALLOWED_TAGS: [
'b', 'i', 'em', 'strong', 'pre', 'code', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
],
ALLOWED_ATTR: ['class']
});
console.log(clean);