網站留言區的 Markdown 連結,預設設定居然會留下 javascript?CommonMark 實測
重點摘要
- 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 標籤 | 轉成純文字 <script> |
整個移除 |
| 表格格子 | — | 4 個 |
| 勾選框 | — | 2 個 |


常見問題
- 預設會原樣保留 script 嗎? 不會。GFM 轉換器預設就把 script 轉成純文字;真正留下的是 javascript 連結。
- 直接
composer install失敗? 我在乾淨環境對原始碼庫直接安裝時,因為開發相依要求ext-curl而失敗;改成在另一個目錄以路徑載入核心,只裝 7 個執行期相依就成功。 - 這樣網站就安全了嗎? 不能這樣說。我只測了這一份自製留言,沒測其他危險網址格式、其他標籤或完整網站防護。
結論
只要網站讓別人輸入 Markdown,這兩個選項就值得打開;表格與勾選框不受影響。但它是 PHP 套件,需要會寫程式才能用,不是給一般人按按鈕的工具。
- 專案:https://github.com/thephpleague/commonmark
- 授權:BSD-3-Clause