投稿日: 5/21/2025
2024年の11/12 ~ 11/29に開催されていました、3問のXSS問題です。
まだ現時点では公開されているようなので、問題と解答・解説のリンク貼ります↓。
問題:https://challenge-xss.quiz.flatt.training/?beatme
解答・解説:https://speakerdeck.com/flatt_security/jie-da-jie-shuo-flatt-security-xss-challenge
高難易度とのことですが、とりあえず取り組んでみました(やっと消化)。
ちなみに、本記事の内容は最初のChallenge 1についてだけです。
Challenge2, 3は正直解説読んでも全くわかりません。
対象のリンクにアクセスすると、以下のページが表示されました。
messageパラメータが付与されてます。
いろいろスクリプトの挿入を試します。
コメントアウトしてみたり, </textarea><script>alert(origin);</script>
としてみたり...
タグとして認識されるものの、アラートは実行されません。CSPヘッダは使われてないし。
ここで、ソースコードも公開されていることを知りました。
ふむふむ、HTMLのテンプレートエンジンであるEJSと、サニタイズにDOMPurifyを使っているようです。
なるほど、これで単にscriptタグを挿入しても無害化されたことで、サブミット後のtextareaからスクリプトが消されていたのですね。
さてさて、解答としてはid属性としてDOMPurifyに認識させる、という手法でした。
解答のスクリプト:<div id="</textarea><script>alert(origin);</script>"></div>
以下がXSS後のHTMLです。
描画されると、textareaが不正に閉じられ、スクリプトがそのまま実行されたことがわかります。
</div>
なしで挿入した場合もXSS成功し、直後のHTMLは同じでした。後はなんでもよさそうです。DOMが破壊されて変な画像のようになったりしてます。
DOMPurifyでは、divタグのid属性が有効で</textarea>~
が無効で、サニタイズ後の描画では親となるtextareaが有効になり、divタグが無効になりました。
解答には、
<%- sanitized %>
ではなく
<%= sanitized %>
としてtextarea内の文字列エスケープをちゃんと行うといったものです。(下記参照)
HTMLタグが文字列として描画されてますね。
なるほどー、DOMPurifyのバイパスについては調べてみると面白そうです。
textareaの扱い含めて、開発側も攻撃手法を知りつつ対策する必要がありますねー。
まだコメントがありません