A Day In The Boy's Life -114ページ目

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

CSRF(Cross Site Request Forgeries)ってリクエスト汚染のことかと思ったらちょっと違うみたいですね。



CSRF問題の概要


例えば、下図のようなServer-A上で動くSNS的サイトがあったとして、会員はログインしてサイトの書き込みページを経由して、記事を書き込んだりできるとします。


- 図1
A Day In The Boy's Life-CSRF図1

CSRFの問題があると、下図のようなまったく関係の無いServer-B上からのリクエストを受け付けてしまう、というってことらしい。


- 図2
A Day In The Boy's Life-CSRF図2


でも、これだけでは明らかにおかしいわけで、そのまま書き込めるのなら認証が不十分であったりセッションハイジャックの問題になります。

CSRFは正規のユーザーに成りすましたリクエストを発行することで書き込みなどの悪意ある処理をさせるようです。

(書き込みならまだかわいいものですけど、オンラインバンクなら振込み完了画面へ不正なリクエストを投げるとかになるのでしょう)


で、どうやって正規のユーザーのリクエストを発行するかというと、会員系サイトの良くあるログインパターンでは、入力したIDとパスワードに対し「次回から入力を省略する」なんてチェックボックスがあったりします。

ここにチェックを入れるとセッション情報Cookieに保存され、次回以降はそのセッション情報を持って自動的にログインなんてするわけです。


なので、CSRF問題の前提になるのはユーザーが正規の手続きを踏んでログインした状態である、ということが前提になるみたいです。

つまり・・・


- 図3
A Day In The Boy's Life-CSRF図3


上図のように、ログインした状態のユーザーに対して、どこかで悪意あるサイトへ誘導させ(操作1)、そこサイトを経由して不正なリクエストを元のサイトへ送りつける(操作2)ということをやるみたいです。

上図の場合では、SNSサイト内で「釣り」をして不正なサイトへ誘導(操作1)、不正なサイト上ではページがJavaScriptで自動ロードされ(操作2)、元のSNSサイトへリクエストが飛ぶということをする。

不正なサイト上で、もう一度クリックさせてもいいのでしょうけど、そうすると「なんか怪しい」ということになりますから、ページを読み込んだと同時にJavaScriptで不正リクエストの発行と、まったく関係の無い別サイトへリダイレクトしてしまう、なんてことで隠蔽してしまうことが多いらしい。


これは、そのサイト内で踏ませなくてもSPAMでばら撒いたメール本文に不正なURLを書いておき、受け取ったユーザーがそのサイトの利用者でかつ、そのサイトにログインしている状態であれば発動してしまいます。


こういうことはセッション情報を抜きにすると結構簡単なエラーチェックだけをしているページでは、そのページで必要なリクエストがそろっていれば簡単に抜けてしまう場合があったりします。

例えば、書き込みページから

1. 会員ID

2. タイトル

3. 記事内容


の3つの情報を書き込み完了ページに送っているとすれば、書き込み完了ページでは、


・ 全てのデータがそろっているか

・ 各データ長が範囲内であるか(タイトルは100Byte以内とか)

・ 各データのフォーマットが正しいか(会員IDは数値のみかとか)


というようなチェックをしますが、それらが正しい情報であればどのページからも受け付けてしまう仕様になっているということはあったりします。


まとめると、下図のように正規の経路(Request1: 書き込みページ→書き込み完了ページ)ではなく、別のサイトも含め他のページからリクエストを発行できてしまう(Request2)脆弱性がある、ってことがCSRFの問題。


- 図4
A Day In The Boy's Life-CSRF図4



CSRFの対策


詳細は最後の参考ページに任せるとして、対策の一つとしては一連の処理にトークン(token)を使うやり方があるみたいです。


- 図5
A Day In The Boy's Life-CSRF図5


トークンは、ワンタイムパスワードのように使い、そのトークンが正しければ処理を受付け、トークンが不正であれば受け付けない、ということで別のサイトやページからのリクエストを遮断するのに用いることができます。
例えば書き込みページでトークンを生成し、書き込み完了ページではそのトークンをチェックして正規のユーザーや処理であるかをチェックします。


※ セッション情報とは全く別のものを使う。じゃないとセッション自体は活きている状態から始まるので意味がない。


ページの経路情報だけ正しければいいんだ、ということで前のページの情報(例えばプログラム名とか)を送りつけてチェックするというのも、そのデータを含めてリクエストを作ってしまえばまったく意味がなくなってしまいますし、リファラーのチェックも簡単に偽造できるということから意味を成さないようですね。


あと、CAPTCHA(ゆがんだ画像から数字とか文字を入力させる例のあれ)を使うのも良いみたいですが、これはトークンをユーザー自身で作るようなもので、手間がかかるのであまりお勧めとはいい難いですよね。

(ブログのコメント書くときはよくあったりしますけど)自分自身が書き込みするのにいちいちCAPTCHAの情報を入力するような面倒なサイトはあまり使いたいとは思いません。


どちらかというと、毎回ログインIDとパスワードを求められる方がいいかも。

あれ、でもCSRF問題があるサイト上では、ログイン時のセッション情報をCookieに持たせる云々の話は関係なく、ログインさえしていたら、そのサイト内で釣られたら終るような・・・?

SPAMメールでばら撒かれた場合、そのサイトにログインしていない状態であれば防ぐことは可能そうだけど・・・。


- 参考サイト

開発者のための正しいCSRF対策


PHP と Web アプリケーションのセキュリティについてのメモ





当たり前のことですが、技術や世の中のスタンダードって変わっていきますよね。

それは、技術の進化だったり、意識の変化・浸透だったり、自分の成長だったり、何れにせよその時代によって求められるレベルというのは変化しています。


それは、進化のときもあれば、解体と再生でプラマイゼロという場合もあるでしょう。

ただ、そのスタンダードの変化に振り回されるエンジニアも多いのでは、と思ったり。



求められる技術平均


求められる技術レベルの平均値というのもどんどんと押し上げられていってるのかな、と感じたりします。

それは全体のレベルが上がっているというより、世の中に情報があふれたり、ユーザーの意識の変化であったりして、技術の成長はしていなくても、ここまでできればOKという感覚だけがかなり一人歩きしている気もします。

ユーザーの目が肥えたせいなのかもしれませんし、インフラの発展によって開発のスピードが上がった結果なのかもしれませんし、技術先進の企業が凄いサービスを打ち出し続けたことによるものなのかもしれません。


ただ、エンジニアのスタート地点というのはいつの時代も一緒だったりもします。

Linuxエンジニアならコマンド覚えて、プログラマーならHello Worldからとか。

教育する方もスタート地点を理解していないわけではないのですが、情報過多な時代とひどくマニュアル化された環境が、スタート地点をレベル1と捉えると、次のマイルストンがレベル3だったり


そして、その成長の過程で、「これなら戦力になる」というお墨付きをもらえるレベルというのだけは、高くなっていってたりします。

PHPer歓迎というところから、セキュリティやアーキテクチャ、デザインにいたるまでごった煮でやれないとダメというような感じで、単にその技術を知っているだけというのでは、なかなか合格点をもらえなかったり。

世の中、これだけ変化しているんだから「ここまでできて当たり前でしょ」という感覚の道程だけが伸びているというか。


例えば、自分から見た新人エンジニアのレベルと、2年目3年目のレベルというのはより高い方向に向いていきます。

自分のスキルの半分ぐらいのレベルは持ってて欲しいと思っても、年々自分も経験値が増えていっているわけで、そのレベルは高くなっていきます。

また、世の中の技術が安定していく過程で、ここレベルまで達成するのは難しいというレベルから、「それは今では当たり前」というレベルへ変化したりもします。


なので、自分たちが新人だった頃に求められたレベルへの過程と、今の新人エンジニアが求められるレベルへの過程というのは随分と違うものになっているのではないかなと。



合格レベルの過程


もちろん、その合格点のレベルに行き着くためのコストというのは、昔と比べて格段に下がっていると思います。

インターネットで調べれば情報が出てくる場合も多いですし、書籍も豊富になってきています。

技術はより安定し、便利で簡単になっていくと、そのレベルに行き着くまでに階段三段飛ばしぐらいの勢いで駆け上がることもできたりします。


先に書いたレベル1の次がレベル3の教育というのも、レベル2の知識は自分で調べましょうね、という具合にひどく個人任せにされているような気もします。

あくまで当面の業務で使う知識レベルが前提ということで、今の技術がカプセル化してしまった要素というのは興味を持ったら調べてみようね、とか。


しかし、その飛ばした分はやはり後々求められる要素というものが含まれていて、「ここまでたどり着いたら、このレベルのことはわかっているよね」ということにギャップが生じたりもします。

とりあえず動くアプリケーションを作るということに専念した結果、セキュリティやアーキテクチャ、アルゴリズムもちゃんと理解しているんだよねぇ、と。


短期間で今のスタンダードな知識レベルを求めれ、それに達したかと思うとそのスタンダードなやり方の中に含まれない知識を求められたりします。

そういうことは求められる状況の中で理解したり、経験の中で身に着けていったりするもんだと思ったりもしますけど、ゴールに達成したならそれは理解しているのだろうという勝手な判断が出来上がってたり。



失敗する環境が無い


求められるレベルに達するには、より深いところに掘り下げていく必要があったりもしますが、その環境というのはなかなか用意されていなかったりします。

ユーザーの求めるサービスレベルが高くなれば失敗できない環境になるでしょうし、開発環境といえど好き勝手にやって良いよ、というわけにもいかなかったりします。


お客さん先に常駐してたりすると余計無いことはしてくれなと言われる割に、トラブルが起きた際の対応マニュアルを書けとかいわれたり。

なので、理論上そうなるであろうということだけで、例外的なことは切り捨ててしか書けないわけですよね。


自分たちの時代ではITの不安定さを理由にしたりもできたりしましたが、今はユーザー目線のスタンダードの変化によってそういうことが許されなくなったりもしています。

(自分としては、システムなんて落ちるもんだと思ってたりもしますけど)

経験豊富なエンジニアであれば、今の環境でどう対処するかということを考えたりもできますが、経験が浅いエンジニアではなかなかその答えがわからなかったりもします。


とりあえずトライしてみる、失敗する、リトライするということを容易にできる環境がなかったりするわけです。
それに対処する方法を知らない、存在しないのに、求められるレベルだけは年々高くなっていっているのではないかな、と。


ここに書いたことは、ひどくマニュアル化したエンジニアを育てようとする企業によって生み出されているのかもしれません。

エンジニア側としては、企業内に自分の自由にコントロールできる環境がないのであれば、それを外に求めるのもいいのかもしれません。

昔と比べ、その環境を持つコストというものは随分と下がっています。

そして、情報豊富なこの時代なりのスタンダードなスキルアップ法というものを身につけていかなくてはならないのかもしれませんね。




小飼弾のアルファギークに逢ってきた (WEB+DB PRESS plusシリーズ)/小飼 弾
¥1,554
Amazon.co.jp

小飼弾氏と様々なアルファギークと呼ばれている方々の対談をまとめたものなので、小難しい用語が並ぶ中でも割とサクサクと読み進められる内容のものでした。

インタービュー自体は2006年から2007年あたりにWEB+DB PRESSで掲載されていたものらしいですが、今でも現役バリバリの人たちなので、サービスを作った舞台裏や生い立ちなどが見て取れて面白かったです。


むしろ今読むから面白いというところも。

例えば、Twitterの創設者のEvan Williamsのインタビューも載っていますが、これが2007年11月。

当時、私はTwitterはニュースサイトで取り上げられていた記憶はあるものの、全然使ってもいませんでした。

今は毎日欠かさず使うサービスになっていますが、その当時Twitterの状況もよく描かれています。

(当時の不安定だったサービスの様子も)


こういったギークな人たちをみると、何かやると決めたらとことん突き進むエネルギーを感じ取れます。

一見無謀にも見て取れますけど、道が無けりゃ自分で作るみたいな芯の強さが見て取れるんですよね。

あとは、それぞれポリシーをもって生きてるんだな、ってことも。

それも、あれこれと好奇心旺盛に自分の目で見て回って、その広い見識の中で「やっぱりこれだ!」という確かな考えが根付くのかなと思ったりしました。


加筆・修正がもちろんあるのでしょうけど、そういったギークな人たちのエンジニア魂のようなものは文章を通しても伝わってきたり。

やっぱり、そういう人たちの言葉を聞いてると自分も一歩でも前に進みたいという思いに駆られます。


目次


#0 Ruby on Rails開発者 David Heinemeire Hansson
「アーキテクト」って言葉を使ったら負け

#1 (株) はてなCTO 伊藤 直也
良いサービスを作るのに、マネジメントはやはり重要

#2 Perl開発者 Larry Wall
優れたソフトウェアも、文化を持たなければ普及しない

#3 livedoor 池邉 智洋 / 谷口 公一 / ma.la
ネットは個人の人生に何をもたらしているか

#4 Twitter Co-founder Evan Williams
大事なのは「好き」を貫けること

#5 The Seasar Projectチーフコミッタ ひが やすを
世の中の根底にあるニーズに合ったものを提供したい

#6 『達人プログラマー』著書 Dave Thomas
コーディングを続けるという情熱が重要。それ以外は取るに足りない

#7 Pathtraq / Japanize開発者 奥 一穂
自分は、コミュニケーションの形態を考えている。ウェブは手段

#8 Mozilla Corporation / jQuery開発者 John Resig
自分が興味を持っているものに手中し、最適化を加える

#9 「Binary 2.0」「スルー力」提唱者 高林 哲
ハッカーに一番重要なのは、「深追い」できること

#10 Perl Mongers Ingy dot Net / Dave Rolsky / Jesse Vincent / C.L. Kao
今どき正気の人はいない。大事なのは役に立つ狂気かどうか

#11 『IT戦士』 天野 仁史 & こんにちはこんにちは! はまちや2
勢い重要。脆弱性とか気にしないでシンプルにリリースすべし

#12 [夫婦対談] (株)はてな 近藤 敦也・令子×小飼 弾・直美
行動を起こしたほうに情報はついてくる

#-1 [スペシャル対談:前編] きたみりゅうじの小飼弾に逢ってきた
アルファギークとSEの現実と

#-2 [スペシャル対談:後編] きたみりゅうじの小飼弾に逢ってきた
知られざる小飼弾の歴史