|
|
||
について。
これはsame originからじゃないとカスタムヘッダの付与ができないよ、ということに依存したCSRF対策ということになります。
ブラウザやプラグインの実装がバグってて、色々組み合わせることでクロスドメインでカスタムヘッダの付与が出来てしまうという可能性はあります。最近もそんなのを見かけましたが、POSTかつカスタムヘッダ付与というのは見てないです。POSTで出来たらクリティカルなバグだと見なされるはずです。今すぐ直せって感じになります。
X-Requested-With検証するのと似たような感じですが、X-Requested-Withを検証するというのは、どちらかというとJSON Hijack対策とか、XMLHttpRequestから来るリクエストかどうか保証したいとかで、あんまり通常のフォーム送信の置き換えやCSRF対策といった文脈ではあまり言及されていないように思います。
で、過去にこれ危険なことあるので使っちゃダメ、みたいな感じで言及されていたりします。ただよくよくみると、これはFlashがクロスドメインでカスタムヘッダの付与が出来るので危ないよ、という話なんですね。
参考文献:
上書きできないヘッダ(リファラ等)が上書きできちゃうとマズイし、CORSのヘッダやポリシーファイルが無いのにクロスドメインでカスタムヘッダ付与できちゃうのもマズイよ、というのが現状。
クロスドメインでリクエストを発行できるようなブラウザプラグインは、CORSと同等のポリシーを持つべきです。全てのプラグインがクロスドメインでカスタムヘッダ付加を禁止してくれてるとは限らないので、そういう意味では安心して使えない、ということになりますが、CORSが出来てその辺のポリシーが明確になってるからもう使っていいんじゃねーの、クロスドメインカスタムヘッダ付与が勝手に出来たらプラグイン側のバグだよね、って言える土壌ができている、といえるんじゃないでしょうか。
古いFlashプラグイン使ってたらその時点で、その人は全サイト安全に使うことが出来ないし、俺達はいつまで古いFlashプラグインが使われたいた場合には危険だから、と言い続けなければいけないんだ。古いFlashプラグイン入ってる時点で危険だろ。セッション持ちたくないとかCookie使いたくないようなケースは多くあるでしょうし、まずリファラを見て、リファラが無いのであればJavaScript有効にしてください、といった具合に、あまりユーザーに不便をかけずにCSRF対策が行えるんじゃないでしょうか。
人間が送ることを保証したい(botによる投稿を抑止したい)のであればどっちみちCAPTCHAが必要ですし、犯行予告を送った人間を逮捕していいということを保証したいのであれば、身分証明書をFAXで送らせるとか郵送で仮パスワードを発行するとか、クレジットカード登録させた上でVプリカは弾くとか、Torのexitノードは全部ブロックするとか、いずれかあるいは全部を行う必要があります。
Safariです。WebKit組み込みブラウザのいくつかも多分そうです。Google Chromeはできません、多分意図的に判別が困難であるようにしています。
プライベートブラウズ中かどうかを検出する汎用的に使える手法は
というものがあるでしょう。例えば多くのユーザーがキャッシュしている可能性が高い画像等の応答速度を調べて全くキャッシュされていないようであれば、それはブラウザのキャッシュを削除した直後であるか、プライベートブラウズ中であると推測できます。多くのユーザーがログインしっぱなしにしているサイトにおいて、ログインしているかどうかを判別する方法があれば、それを複数のサイトに対して検証して、全くログインしているサービスがなければそれはCookieをクリアした直後であるか、プライベートブラウズ中であると推測できます。このように、完璧に防ぐことはそもそも難しいのですが、プライベートブラウズ中であるかどうかを明確に判別できるのは、(自分の知ってる範囲で)Safari(及びいくつかのWebKit組み込みブラウザ)だけで、しかも最近になって「明確に」プライベートブラウズ中であることを条件にして外部から観測可能な挙動を変えるということを仕様として盛りこんできました。
http://www.apple.com/jp/safari/
あなたのプライバシーを重視するSafariは、最新のプライバシー標準である「Do Not Track」に対応しています。「プライバシー」パネルでトラッキングを停止するように設定すると、あなたが訪れたウェブサイトがあなたの行動をオンラインで追跡しないよう、そのウェブサイトに要求を送信します。プライベートブラウズを使っている場合も、ウェブサイトに追跡をしないように要求します。
Safari利用者で、ある程度固定のIPアドレスを使っているユーザーのDNTヘッダの送信状況を調べれば、そのユーザーがプライベートブラウズを利用中かどうかが高い精度で判別できるでしょう。普段はDNTを送信していないのにDNTを送信していたら、それはプライベートブラウズを使っているということです。他の手法でもできるので、多分利用はされないでしょうけれど。
ということに議論の余地があると思います。例えば、ブラウザベースでのDoS攻撃に加担させられたり、CSRFで犯行予告を書きこまされたりしたときに、PC側に証拠が残らないという問題があります。ディスクキャッシュを使っていて、履歴を復元可能であれば、それはそれでブラウザ側の脆弱性です。ちゃんと証拠が消されなければいけません。
プライベートブラウズ中であれば、殆どのサイトはログアウトした状態でしょうから、Webサイトの脆弱性、XSSやCSRFを利用してアカウントの情報を盗み出すという攻撃には遭遇しにくいでしょう。ログイン状態の有無に関わらず成立するような攻撃を受けた場合に、その結果、証拠が自動的に消されることになります。ユーザーは通常、攻撃を受けたことに気付きませんし、プライベートブラウズを終了したタイミングで証拠が全て消えてしまうため、後から検証することもできなくなります。
証拠が残らないなら残らないで無罪で確定ということであれば良いのですが、罠にはめられた人が普段からDoS攻撃を行いそうだったり殺人予告を行いそうな人だった場合、区別が付かなくなるのではないかと思います。
http://subtech.g.hatena.ne.jp/mala/20121023/1351004574 を書いてちょっと嫌な予感がしたので調べてみたのですが
例えばSleipnirの場合
で、ローカルのHTMLファイルからローカルファイルを読み取ってリモートに送るということが出来てしまう。
いずれにせよ、httpからfile://への移動は制限されているので、Webページ閲覧中にいきなりローカルファイルが読み取られたりすることはないです。Appleは問題を認識して、Mountain Lionにおいては、SafariでダウンロードしたファイルをSafariで開く際には安全になるようにしたけど、例えば標準ブラウザをSafariにしていてサブでSleipnirを使っているような人がSleipnirでダウンロードしたHTMLファイルをダブルクリックで開くとSafariではローカルファイル読み放題の状態で開かれてしまう。逆もまたしかり。
問題はいくつかあって、
例としてSleipnirを挙げたけどこれはサードパーティのアプリ全般の問題で、Appleは自社製品を組み合わせて使った場合には影響が軽減するような措置を取ったわけだけど、結局アプリ側が com.apple.quarantine を付けてない場合には、SafariのローカルHTMLファイルの取り扱い自体は変わっていないわけだし、WebKit組み込みのブラウザがどうすべきなのかという指針も示していない。サードパーティのアプリが受信したHTMLファイルにフラグ付けずにSafariで開くような機能付けてたら結局のところそのHTMLファイルからはローカルファイルを読み取ってどっかに送るということは出来てしまう。
ただちに危険だというものではなく、もうユーザーに(ある程度は)そういうものだと認識してもらったほうが良いと思っているので、ブラウザ作ってる人はどういう対応をするかも含めてゆっくり検討すれば良いと思います。
setAllowFileAccessFromFileURLs と setAllowUniversalAccessFromFileURLs というオプションがあるので、それを使うと良いです。
これはGoogle Chromeが対応したときに作られたはずです。
Firefoxと同等のポリシーをサポートするかどうかについての議論
そして、ローカルHTMLファイル上でJavaScriptの開発/実行をする場合に、それなりに副作用が大きい変更であるので、Google Chromeはallow-file-access-from-filesという起動オプションで挙動を変えられるようになっている。
アプリケーション実行プラットフォームとしてHTMLを見た場合には「出来て当然、出来なくては困る」のですが、単なるリッチテキストフォーマットとしてHTMLを見た場合には「異常な仕様」で、ブラウザ側が対処しないことにはどうにもならない。いずれにせよローカルHTMLファイルを開くときは気を付けなくてはいけなくて、ユーザーは自分が使っているブラウザのポリシーを把握していなければ安全にローカルHTMLファイルを開けない。この状況は当面改善しないので信用できないHTMLファイルを開くのであればw3mを使うと良い。readme.htmlみたいに単にドキュメントとしてHTMLを配布したい側へのアドバイスは、JavaScriptを含めないことです。特に外部からロードするJavaScriptを含めてしまうと、そのHTMLファイルが安全であったのかどうか後から全く検証ができなくなります。
Larisa2013/03/06 13:59This is just the perfect awnser for all forum members
glmzvoqet2013/03/11 01:17k5PiQC , [url=http://wlpafvfxqwnx.com/]wlpafvfxqwnx[/url], [link=http://snzqlhpkhjrp.com/]snzqlhpkhjrp[/link], http://qhucfcvvywmg.com/
http://subtech.g.hatena.ne.jp/mala/20110425/1303730089 を書いた時から、少し変化があったので書いておきます。
SafariにおいてローカルHTMLファイルかローカルファイルを読み取ることが出来るというのは広く知られている問題で、脆弱性として報告されるからには何かしら「攻撃を容易にする方法があった」のだと理解していました。で、表現の問題だと思うのですが、タイトルが"リモートからローカルファイルを読み取り可能な脆弱性"となってて、これだと脅威の度合いを勘違いする人が多いのではという気がします。自分の知る限り、あくまでfile://を何らかの方法でユーザーに手動で開かせる必要があります。
報告者のmasa141421356さんの話を聞いたところダウンロードしたファイルを強制的に開かせる、というものではありませんでしたが、それなりに脅威の度合いが高いなと納得できるものでした。Aaron Sigelという人も報告していて、もっと凶悪な方法があるのかも知れません。が、自分は把握してません。
10/24追記: やっぱWebから直接ではなくて何らかの方法で悪意のあるファイル開かせる必要があるということだと思います
httpから、file:// のURLに遷移したり、iframeで読み込んだりwindow.openで開いたりするのは以前から制限されていて自分の知る限り方法はありません。ただ、いろんな方法で騙して悪意のあるローカルHTMLファイルを手動で開かせようとすることは出来るでしょう。
https://gist.github.com/3937884
説明するのが既に大分面倒なのですが、簡単に言うと、OSXでは対応しているアプリ経由でインターネットからダウンロードしたファイル全般に com.apple.quarantine という拡張属性が付きます。このフラグがついている場合には、インターネットからダウンロードしたファイルですが開いてよろしいですか、と警告を出したりします。
で、それが
という変更がなされました。Mountain LionのSafari6.0.1の隔離モードでHTMLファイルを開いた場合、Same originが自分自身のHTMLファイルに制限されます。これはGoogle ChromeのローカルファイルにおけるSame origin policyと同じです。
Windows版の修正が出るかというと、そもそも開発継続するのかどうかわからないですし、LionとMountain Lionで既に挙動が違っていることから分かるように、対応するとしても結構面倒くさいのではないかと思います。「Lionではファイルを開く際に警告してロック解除」「Mountain Lionではフラグを維持したまま安全なモードでHTMLファイルを開く」と対応が違います。これは、OSがダウンロードしたファイルに対して「一律で警告を出す」のか、それとも「アプリケーション側が面倒を見る」のかという問題です。
信頼出来ない危険なファイル、あるいは、危険なプロトコルに対してOSが一律で警告を出して、アプリ側では配慮しないというポリシーもありでしょうし、Mountain LionのSafariのようにフラグを見て、Same origin policyを切り替えるというのもありでしょう。見た目には全然わからないのでややこしいわけですが。Windowsで、これをやろうとするとZoneIdというのがあります。IEと同じことをやらないとダメってことですね。
Safariでfile://を開くのは、依然としてリスクがある状態であるので、単に「脆弱性が修正された」「Safari6.0.1以降にアップデートを」とアナウンスされてしまうと、かえって危険な状態なのではないかと思います。最新版にアップデートしておけば安心といったものではないですし、ここらへんのポリシーがブラウザ毎にバラバラなのは今に始まったことではないのですし、すぐに解決するような問題ではないです。
以上です。
リファラを使ったCSRF対策では多くの場合、想定していない、外部サイトのリファラが付いていたらエラーにする、ということが行われます。
一方で、ブラウザ側の設定に関わらず、リファラはいくつかの方法で消せます。
なので、「リファラのみ」使ってCSRF対策をしているときに、正規の手順以外でのフォーム送信を完全に塞ぎたいのであれば、リファラが空の場合でもリクエストを拒否しなくてはいけません。
そして、リファラは送信が必須のヘッダではありません。RFC2616では、UserAgentにはリファラを送信するかどうか選択する設定を作ることが推奨されています。
しかし現状、設定自体が存在しなかったり、about:configであったり、起動オプションであったり、拡張機能が必要であったりします。ユーザーに見える場所に設定があるのはモダンなブラウザの中ではOperaだけです。
リファラを使ってCSRF対策をするということは、確実に「リファラを送信しない設定にしている人がサービスを使えなくなる」という不便を強いることになります。すでにリファラを送信しないと使えないサービスや、何の脈絡もなく唐突にエラーページを返してくるサービスが数多くあります。tokenによるCSRF対策が行われていながらも「念のため」といってリファラのチェックも行われていることもあります。ログに残しておけば十分です。
いつの話だよ。それは、ずいぶん昔の話です。
多分何かと勘違いしています。例えばあなたがpixivから画像をダウンロードしたかったり、i-driveからワレズしたり、Proxomitronで少年ナイフしたり、そういうので任意のリファラを「自分の意志」でセット出来るのは何の問題もないのです。自分の意思で、自分の送信するリクエストを任意に書き換えられるのは、当たり前です。
罠を踏ませて任意のリファラを送出できることが問題なのです。
「リファラを使ってCSRF対策をしているサイトが数多く有るために」リファラの誤送信や、偽装が出来るのは、クリティカルなバグと見なされています。もしあなたが、そういうことが出来るブラウザやプラグインを把握しているならば、バグ報告してください、すべきです。FirefoxやChromeだったら報奨金がもらえるでしょう。「クックック、リファラを偽装するのは簡単にできるのだよ、おっと悪用されるといけないので方法は公開できないのだが」と言ってる人がいたら、多分その人は中二病か偽物です。
自分はリファラを使ったCSRF対策を推奨しません。それは「対策として不完全だから」ではありません。リファラを使ったCSRF対策は、(任意のリファラを送信できるようなUserAgentが無いという前提で)安全です。そしてとても簡単に実装することができます。何らかの事情でサービスのコード自体を書き換えられなくても、例えばApacheの設定ファイルでも対策ができます。(POSTリクエスト時に想定外のリファラだったら403)
リファラを使ったCSRF対策は無意味ではなく、ちゃんと対策になります。だからこそやめるべきです。リファラを使ったCSRF対策が「ちゃんと機能する」状態を保ち続けるために、本来気軽にオンオフできるはずだったリファラを送信するかどうかの設定が、奥深くに覆い隠され、あるいは完全になくなっています。ユーザーから選択肢を奪うから良くないのです。
こんなこといってWebの未来を憂いたところで実際のところ大半のユーザーのデフォルト設定で動けば別にいいじゃん、設定変える人は自己責任、みたいな開発者も多くいると思います。
なので現実的な話をすると、奥野みたいな面倒くさい人間にイチャモンつけられるのでやめたほうがいいです。 http://oquno.com/log/eid2593.html
asfaなんだこの技術論破しましたみたいな厨二記事。リファラーが偽装出来ようが出来るまいが、ユーザーから送られてきたデータを信用してチェックに使うこと自体が誤りだろーがカス。おまえはユーザーからのデータを性善説でチェックしてんだろ。つーかやってるぞこいつ。
s_hskzなんなんだ、このコメント。www ↑
fukken↑↑
UbaldoIt's great to read something that's both enojabyle and provides pragmatisdc solutions.
ekqnjwUfN11G , [url=http://oslcudlbcavd.com/]oslcudlbcavd[/url], [link=http://kumvqqjvverq.com/]kumvqqjvverq[/link], http://ducsoygsabkk.com/
kbsgkajn7lgpZ <a href="http://kaprvambejje.com/">kaprvambejje</a>
auffkuhmwnnW0inI9 , [url=http://xrpcgwpqkhrd.com/]xrpcgwpqkhrd[/url], [link=http://eabkxociyamt.com/]eabkxociyamt[/link], http://rbsdqoddvthc.com/
gzaqvxxpaeYaoVfd , [url=http://dhkqeqjlklyt.com/]dhkqeqjlklyt[/url], [link=http://szxvvxjajgaj.com/]szxvvxjajgaj[/link], http://snfmuuxewozw.com/
https://github.com/felixge/faster-than-c がちょっと話題になってたので
取り上げられてる最適化コードの部分が要約すると「eval使って動的に最適化されたコード生成すると速い」みたいになるんだけど、正確にはevalじゃなくてnew Functionを使っていて、evalとnew Functionには違いがある。new Functionと違って、evalは呼び出した箇所のcontextで実行される。なので例えばevalするコードをevalしておくと、過去に遡ってevalできるので便利。
var env_history = []; var save_env = "env_history.unshift([function(code){return eval(code)}, arguments])"; function back(num){ return { eval: env_history[num][0], arguments: env_history[num][1] } } function hoge(p){ eval(save_env); var a = "hoge " + p; } hoge(12345); hoge(2345); // take me back a = back(0).eval("a") b = back(1).eval("a")
逆に言うと、evalで動的に生成された関数がクロージャになっていて、evalを呼び出した箇所のcontextを維持しなくてはいけないような状況が発生するとメモリリークが発生してしまう。なので、こういうおかしなことをする必要がなく、"単純に"文字列から関数を動的に生成したいだけなら、new Functionを使うべき。もちろん、多くの場合はそういうことをやる必要自体がない。
ループ展開済みのコードをnew Functionで生成しておくというのは割とよく知られている(と思う)テクニックで、evalやnew Function自体はとても遅い。処理系によってはevalのほうが速かったりするんだけど、どうせこれは一回きりなので、あんまり気にする必要がない。eval使う必然性がないならnew Functionを使ったほうが良いと思います。
CemreSurprising to think of smeothing like that
hphhwkdjrABQjzu <a href="http://frlhmxbwlqmg.com/">frlhmxbwlqmg</a>
nytduurhudvoKEhHQ <a href="http://qtebncdmwxll.com/">qtebncdmwxll</a>
rydwpobb3zv73Y , [url=http://rgxsqzwundue.com/]rgxsqzwundue[/url], [link=http://aspzcqlpqxaf.com/]aspzcqlpqxaf[/link], http://bpqedvlxkrfh.com/