2026年3月1日
「unsafe = true」の裏側にあるXSSの脅威
サイトカスタマイズをしていたところ、セキュリティの壁に当たったので記録しておく。
ドット絵のチェックボックスを表示
「ishikawaの酒場」のフロントページに、現在の活動状況を示すチェックボックスを作ろうとした時のことだ。Markdown記法でチェックボックスを作成するとビュレットが表示されてしまい、デザインに欠ける。(以下参照)
- 十分な睡眠と適切な飲酒
- Pythonの学習(Djangoも含む)
- 情報セキュリティの学習
そこで、HTMLを直接埋め込むことでドットのチェックボックスにブラッシュアップできた。(以下参照)
Markdown で HTML を作動させる
NES.cssのレトロなチェックボックスを使おうとMarkdownに直接HTMLを書き込んでも、ビルドしてみると反映されない。原因は、Hugoの標準Markdownレンダラーである「Goldmark」の安全装置が働いていたからだ。HTMLの使用を許可するには、hugo.tomlに以下の設定を追記する。
[markup.goldmark.renderer]
unsafe = true
なぜ Hugo は HTML を無視するのか?
Hugoはパーサーとして「Goldmark」を採用している。「Goldmark」はMarkdownレンダラーの一種で、標準設定でMarkdown内のHTMLは安全ではないとして除去されるようになっている。これにはXSSという非常に重要な脆弱性を防ぐ意図がある。
XSS(クロスサイトスクリプティング)とは何か
XSSとは、サイトの脆弱性を突いて攻撃者が悪意のあるスクリプトを埋め込み、それを閲覧したユーザーのブラウザで実行させるサイバー攻撃のことだ。もし、不特定多数が記事を投稿できるサイトで HTMLを無効化(サニタイズ) していなかったらどうなるか?悪意のある者が、以下のようなコードを紛れ込ませるかもしれない。
<img src="invalid" onerror="alert('セッション情報を盗みました: ' + document.cookie);">
このスクリプトは、、、
src="invalid"(存在しない画像パス)を指定することで、わざと読み込みエラーを発生させる。- エラーが起きる、
onerror属性に書かれたJavaScriptが作動する。 - この例では
alertが出るだけだか、実際はdocument.cookie(セッション情報など)を攻撃者のサーバーへ送信させるようなコードが書かれることが多い。
総括
今回のケースでは 「自分で自分のサイトにHTMLを書く」 ためリスクは低い。不特定多数がコメントを残せるようなサイトであれば、この 「HTMLの無効化」 は絶対に欠かせない防衛ラインとなる。利便性と安全性のトレードオフをどう管理するか、難しい課題だと感じた。