おもろいことしかやらない

🗣: バイクに乗ったり、ものづくりしたり、ひたすら寝たり。

JavaScriptのクロスサイトスクリプティングについて調べてみた

最近は「使うだけ」ではなく、設計レベルを目指してJavaScriptを勉強中です。 JavaScript本格入門を読んでいますが、jsの生い立ち、クロスブラウザの問題の背景を知ることができて、読み応えがある感じです。

そこで、「JSはセキュリティホールが多い」という誤解が一時期広まったと書いてありました。 これは、JSが動作するブラウザのセキュリティ対策が不完全だったことも相まって、JSの不人気の原因になってしまったようです。

記憶にも新しいニュースを載せておきます。 www.itmedia.co.jp

上記のようなモーダルを出す、という実装は、環境さえあれば手軽に実行できてしまうものなので、 それが誤解されてこのような事件に発展することもあるかと思います。

この機会に、理解があいまいだったJSで引き起こされる「クロスサイトスクリプティング」についてまとめていきます。

ゴール

初心者にクロスサイトスクリプティングがざっくり伝わる説明をする。

説明

*1クロスサイトスクリプティング(英: cross site scripting)とは、Webアプリケーションの脆弱性[1]もしくはそれを利用した攻撃。 xss説明の図

①悪意のある人間がJSを使い、WebサイトのURLのパラメータやDOMを操作して、htmlを改ざんする。

②Webサイトを閲覧し、そのhtmlが表示されたユーザーが、別のページに誘導されてしまったり、不正に個人情報を抜き取られてしまう。

という流れです。この話は何度か聞いたことがありましたが、 では具体的にどういった実装が人々に不安をもたらしたり、害悪があるのかについて疑問でした。 いろんなパターンがあると思いますが、

モーダルを出して不安を煽る文句を見せる

モーダルを消すとリダイレクトする

といったパターンが多いようです。

そもそもなぜこのような操作がJSでできてしまうのか

実装によって異なりますが、

サーバサイドで不正なリクエストを受け取り、本来の実装とは異なるhtmlが返却される

という事象に集約されるようです。

不正なリクエストとは、不正な機能の載ったページをくださいという要求をサーバサイド側にするということです。 サーバサイドでは、このような悪用を防ぐ為に、不正なリクエストがあった時に安全なページを表示する為に工夫をすることができます。

エスケープ

ここではRubyを使ったエスケープという工夫を見ていきます。

docs.ruby-lang.org

例えば、攻撃者が悪意を持って

https://www.サイトURL?params=< script type= \"text/javascript" > alert("警告") < /script>

というコードをリクエストしたとします。(コピペで実行できないように、実際のものに少し手を加えてあります🙇‍♂️)

このままでは、htmlでparamsの値が表示される部分に、モーダルが出てきてしまいます。

これを、ブラウザがモーダルとして解釈しないように、ただの文字列にします。(プログラミングのコードではなく、文章にしてブラウザに伝える命令を変えてしまいます)

p CGI.escapeHTML('< script type= \"text/javascript">alert("警告") \')

#=> "&lt;script type=&quot;text/javascript&quot;&gt;alert(&quot;警告&quot;)&lt;/script&gt;"

すると、#=>以降の文字列としてブラウザに解釈され、モーダルは出ずにコードだけがWebページに表示されるようになります。

Railsのビューヘルパー

上記はサーバサイド言語のRubyを使って説明していますが、アプリケーションを作るフレームワークでもすでに実装されています。 不正なURLにリダイレクトさせたくない時は、url_encodeも有効です。

ERB::Util - html_escape github.com

ActionView - FormTagHelper github.com

この部分は、erbでフォームを作るメソッドです。 フォーム内の文字がエスケープされるように処理が書かれています。

生い立ちを忘れずにメソッドの役割を理解する

今はこのような対策がWebアプリを作る際にすでに用意されているので、私個人として、使う時には意識をしない問題だったと思います。

これはあくまでブラウザが実装者の意図しない命令を解釈をしてしまうことでも引き起こされるので、今後の開発に役立てていこうと思います。

アイコン:

Icons made by Flat Icons, DinosoftLabs, and Freepik from www.flaticon.com

ありがとうございます。

(あまりJSの話ができなかった…)

*1:Wikipediaより