懶惰之最|GitHub 實測

網站留言區的 Markdown 連結,預設設定居然會留下 javascript?CommonMark 實測

2026-11-02|專案:thephpleague/commonmark|Markdown 版

重點摘要

  • CommonMark 預設的 GFM 轉換器,會把留言裡的 javascript: 連結原樣留在輸出的 HTML 裡(實測 1 個連結留著)。
  • 同一份留言裡的 script 標籤,預設就被轉成純文字,不會原樣保留。
  • 設定 html_input=strip 與 allow_unsafe_links=false 後,連結只剩文字、script 整個移除,4 個表格格子與 2 個勾選框照常輸出。
  • 它是 PHP 套件,需要會寫程式;本次只測一份自製留言,不代表整個網站安全。
  • 結論: 網站讓人輸入 Markdown 時,這兩個選項值得打開。
  • 適合: 自己架網站、會寫 PHP、開放訪客用 Markdown 留言或投稿的人
  • 不適合: 不會寫程式的人,或想要一鍵就保證整站安全的人
實測項目 結果
安裝(含 7 個相依) 約 14 秒
預設:javascript 連結 留著
預設:script 標籤 轉成純文字
安全設定:javascript 連結 只剩文字
安全設定:script 標籤 移除
安全設定:表格格子/勾選框 4 個/2 個

假設你自己架了一個小網站,開放訪客用 Markdown 留言。某天有人留了一個「領取優惠」的連結,看起來沒什麼問題。但這個連結的網址不是 https,而是 javascript:alert(1)——訪客一點,那段程式就在你的網站頁面上執行。

這種事要怎麼在「把 Markdown 轉成網頁」這一步就擋掉?我拿 PHP 套件 CommonMark 實際測了一次。測試設備:Mac mini M4 Pro(12 核、64GB),Linux arm64、PHP 8.2.35。

下載

CommonMark 是 PHP 套件,用 Composer 安裝(官方套件名 league/commonmark)。本次測的是原始碼 3164fa3d(BSD-3-Clause)。我在乾淨環境裝好 php-cli、php-mbstring、composer,再以路徑載入原始碼,相依套件共 7 個,整個安裝約 14 秒。

apt-get install -y php-cli php-mbstring composer
composer require league/commonmark

測試檔

自製一份留言 comment.md:標題、兩列表格、兩個勾選框、一個 javascript 連結、一個 script 標籤。

# 本週工作

| 工作 | 狀態 |
| --- | --- |
| 寫報告 | 完成 |
| 整理照片 | 進行中 |

- [x] 寄出報告
- [ ] 整理照片

[領取優惠](javascript:alert(1))

<script>alert('demo')</script>

跑起來

轉換程式只差一行設定:預設,或是加上兩個選項。

use League\CommonMark\GithubFlavoredMarkdownConverter;

// 預設
$c = new GithubFlavoredMarkdownConverter();
// 安全設定
$c = new GithubFlavoredMarkdownConverter([
    'html_input' => 'strip',
    'allow_unsafe_links' => false,
]);
echo $c->convert(file_get_contents('comment.md'));
項目 預設 安全設定
javascript 連結 <a href="javascript:alert(1)">領取優惠</a>(留著) <a>領取優惠</a>(只剩文字)
script 標籤 轉成純文字 &lt;script> 整個移除
表格格子 — 4 個
勾選框 — 2 個

預設設定的輸出

安全設定的輸出

常見問題

結論

只要網站讓別人輸入 Markdown,這兩個選項就值得打開;表格與勾選框不受影響。但它是 PHP 套件,需要會寫程式才能用,不是給一般人按按鈕的工具。

測試設備:Mac mini M4 Pro(12 核、64GB)。內容依實際執行結果撰寫,數據為撰寫當時的實測值。

← 所有實測