ひがやすを技術ブログ

電通国際情報サービスのプログラマ

JavaBeansに対するリフレクションとClassLoader脆弱性

今回の問題は、(SA)Strutsだけの問題ではなく、いろんなフレームワークでもちゃんと調べた方が良い話しなので、もう少し詳しく書いておきます。


Javaで、JavaBeansのプロパティにアクセスする場合、


PropertyDescriptor[] descriptors = Introspector.getBeanInfo(クラス).getPropertyDescriptors();
で取得できるPropertyDescriptorを使うことがほとんどです。この中に、classプロパティは含まれます。
ここまでは良くて、ネストしたリクエストパラメータ(class.classLoader.xxxなど)をJavaBeansにセットする時に、BeanInfo.getPropertyDescriptors()で取得したものをそのまま使うのが問題なのです。


Seasar2(BeanDesc)では、classプロパティとObjectのプロパティは除外してます。
Seasar2に対応したフレームワークで、HOT deployをサポートしているフレームワークは、まちがいなくBeanDescを使っています。標準のjava.beans.Introspectorを使うとHOT deployがうまく行かないからです。
なので、TeedaS2JSFなども大丈夫。S2Strutsは追記の方に書いてあります。


commons BeanUtilsを使っている場合は、今回の問題が発生するので、BeanUtilsにパッチを当てて、classプロパティとObjectのプロパティを対象外にするのが、根本的な対応だと思います(自分ならそうします)。
パラメータ名を正規表現ではじくだとかは、Objectのプロパティが将来的に増えた時に、ちょっと心配。


commons BeanUtils以外では、SpringにもBeanUtilsというクラスがあったと思うので、Springな人は、チェックしましょう。


追記:BeanUtilsレベルでは、Objectのプロパティにアクセスできても良いんじゃないかという意見ももっともですが、"aaa.bbb.ccc"のようなある種の式言語でObjectのプロパティにアクセスできると今回のようなセキュリティーホールが発生するリスクがあるので、BeanUtilsレベルで止めていた方が安全じゃないかなと思います。セキュリティーの話しなので、固い方に振っておいた方が良いという意味。
追記2:S2Strutsは、1.2はアウト。1.3はまだ、調べ中です。
追記3:S2Struts 1.3はPOJO ActionはOK、POJO ActionFormはNGです。
追記4:さらに懸賞の結果、S2Strutsは1.2も1.3もPOJO ActionはOK、POJO ActionFormはNGでした。

StrutsのClassLoader脆弱性はSAStrutsに影響しません

Struts2に見つかった脆弱性と同様の脆弱性がStruts1系にも見つかりました。
Apache Struts 2の脆弱性が、サポート終了のApache Struts 1にも影響


HTTP(S)のリクエストでJavaのClassLoaderのメソッドが呼び出せてしまうという脆弱性です。


もう少し噛み砕いて言えば、リクエストのパラメータをJavaBeansにセットする時に、リフレクションを使い、パラメータ名にaaa.bbb.cccのようなネストした名前をサポートしているフレームワークは同様の問題が起こる可能性があります。
パラメータ名をclass.classLoader.xxxのような感じにして、ClassLoaderのメソッドを呼び出す訳です。


このような問題を起こすリフレクションフレームワークで最も有名なのは、Apache Commons BeanUtilsです。リクエストのパラメータをBeanUtilsを使って、JavaBeansにセットしているフレームワークは、Strutsに限らず同じことが起きると思います。


SAStrutsは、リクエストパラメータをJavaBeansにセットするのに、BeanDescという独自フレームワークを使っていて、BeanDescはclassプロパティにアクセスできないようになっているので大丈夫です。
これは、小林さんがTwitterで言っている通りです。
https://twitter.com/koichik/status/459277890824052736


Seasar2系のWebフレームワークで、リクエストパラメータをJavaBeansにセットするのに、BeanDescを使っているなら、SAStrutsと同様に大丈夫です。独自もしくは、BeanUtilsを使っているWebフレームワークは、至急確認をしてください。


リクエストパラメータをJavaBeansにセットするのに、BeanUtilsではなく、OGNLを使っているプロジェクトも危険です(だと思う)。これが元々Struts2で指摘されていた問題です。

ムービープロトタイピング

pixtuneというアプリをリリースしました。
pixtuneをひとことで説明すると、「Play the moment」。
自分の撮った写真と、写真を撮った当時にはやっていた曲を一緒に楽しむアプリです。どういうアプリなのかは、動画を見た方が早いと思うので、まずはこちらをどうぞ。


無料なので、興味がある方は、ぜひダウンロードしてください。
https://itunes.apple.com/jp/app/pixtune/id722162353?mt=8


今回は、このアプリの開発に使ったムービープロトタイピングという開発手法を紹介したいと思います。
ムービープロトタイピングは、私が勝手につけた名前(大目に見てください)で、アプリのプロトタイプをムービーで高速に行う手法です。プロトタイピングの手法としては、ペーパープロトタイピングが、手軽かつ効果的で、このプロジェクトでも、最初、ペーパープロトタイピングを使っていて機能が見え始めたところで、ムービープロトタイピングに切り替えました。


ペーパープロトタイピングの良いところ(私が個人的に良いと持っている点)は、デザイン等の変わりやすい要素にとらわれずに、アプリの機能の洗い出しや操作フローの確認がとれるところです。
弱点は、UI/UX的(UXと書くとこだわりのある人がいらっしゃると思いますが、ここは軽く流してください)な確認があまりとれないところ。Webアプリのような紹介メインのアプリの場合、それでも何とかなりますが、タッチ主体のアプリの場合、UI/UX勝負みたいなところがあるので、そこが確認できないと、プロトタイプの価値がだいぶ減ります。
プロトタイプの意味は、工数をかけずに、早期に、アプリのコアとなる面白さを確認することだと思っているので、UI/UX勝負なアプリで、勝負所が確認できないとその意味があまり無いのです。


そこで、登場するのが、ムービープロトタイピング。アプリの動きが重要な部分をムービーで軽く作ってみて確認をする手法です。ムービーを作るのは、とても大変な感じがすると思いますが、今回のアプリの場合、最初のPlayerの画面、次の月を選ぶ画面、それぞれ一時間くらいで出来ています。
チームにAfter Effects使いがいるので、その人に作ってもらいました。デザイナが、イラレで、静止画のイメージを作り、After Effects使いが、その素材で、ムービーを作る感じ。
口頭で動きの仕様を決めるのはまず無理で、これまでのやり方だと、動きの仕様はアプリを作ってみないと決められた無かったと思いますが、プロトタイプムービーがあると、仕様を決める場でいろいろ試すことも出来るので、動きの仕様を決めることが、開発の早い段階できるのです。このメリットは、本当に大きいなと開発していて感じました。


今回は、プロトタイプムービーを制作会社に渡して、PVを作ってもらいました。制作会社にイメージを伝えるためのインプットにも、プロトタイプムービーは役に立ちます。


ムービープロトタイピングの弱点は、After Effects使いが、そんなに簡単には見つからないところ。今回は、ラッキーだったと思います。


結局、従来のプロトタイプ手法は、UI/UXが重要なアプリでは、大切な部分の洗い出しが出来ません。今後は、動きを短時間で確認するプロトタイプ手法が必要ななってきます。その一つとして、今回は、ムービープロトタイピングを紹介しました。


最後にpixtuneのダウンロードリンクをもう一度張っておきます。
https://itunes.apple.com/jp/app/pixtune/id722162353?mt=8

良いエンジニアの育て方

人を育てるというのは、とても難しい。
なぜなら、育てる方も未完成な人間だから。
ちょっと経験値のある未完成な人が、経験値の少ない未完成な人と、ともに冒険をし、ともにレベルをあげていくことが、人を育てるってことだと思う。
人を育てようと思うと、どうしても上から目線になってしまう。上から目線だと気持ちも相手に伝わりにくい。気持ちが伝わらないと相手もうまく成長してくれない。
だから、人を育てる機会があったら、ともに冒険をする仲間を持ったと考えよう。きっとその方がうまくいく。


それでは、自分の話をしよう。自分というよりは自分たちの話かな。


2010年、自分は、昼間、ブラ三をやりながら、新規ビジネスの企画を考えたり、プロトタイプを作っていたりしていた。ブラ三をやっていたのは、当然ソーシャルアプリというものを学ぶためだ。ブラ三の能力はかなり向上したけど、仕事ではたいした結果が出せなかった。特に企画考えたりするところが。


そんな行き詰まっているときに、電通の人から、「一緒に何か楽しいことしない?」と誘われた。企画力を磨きたかった自分は、その誘いに乗ることにした。
そのときに、一緒に電通に連れて行く人を、部の若手の中から募集することにした。「電通にいって何か楽しいことしたいと思っているんだけど、一緒にいく人手を挙げて」みたいな誘い方だったと思う。
技術的には、HTML5, CSS3, JavaScriptでやる予定だったので、技術力は特に問わないことにした。2011年の早い段階で、HTML5やCSS3に精通した人がそうはいるとは思えなかったからね。


そんな中で、応募してきたのが、彼女だった。
彼女は、応募してきた時点では、入社二年目の冬。うちの部の若手は、最新技術動向をよく調べているので、いろんな技術を表面的には知っているけど、サンプルより深くは知らないくらいの技術力だったと思う。まぁ、技術力は普通って感じかな。


最初、「CSS3アニメーション・ブック」

魅せるスマートフォンサイトを実現!CSS3アニメーション・ブック for iPhone & Android

魅せるスマートフォンサイトを実現!CSS3アニメーション・ブック for iPhone & Android

を自習してもらい、その後、アニメーションの基礎を学ぶために、ActionScript3アニメーションをHTML5, CSS3, JavaSciptに移植するということをやってもらった。
ActionScript 3.0 アニメーション

ActionScript 3.0 アニメーション


この本は、結構難しいので、最初にActionScript3部分の解説をし、実装のヒントを与えた上で、実装してもらい、実装後コードレビューを行った。
後で、彼女から聞いた話だけど、この学習法は、かなり効果的で、自信がついたらしい。
効果的だったのは以下の理由から。

  • 課題が数時間で解ける程度の規模で、達成感が得やすいこと
  • 適度に頭を使う難易度だったこと
  • コードレビューによって良いコードの書き方を学べたこと


このたくさんのスニペットを作るという作業を、僕たちは素振りをするといっていた。何事も基礎が重要。この素振りを二ヶ月ちょっと続けた。


素振りが終わった後、僕らは、ペアプロでアプリを作り始めた。正確に言うとペアプロをさらに進めたペアシンキングという開発手法をとっている。


ペアシンキングとは、プログラミングだけでなく、考えることもペアで行う手法(自分たちで勝手に命名)のことだ。なぜ自分はこう考えたのかをすべて彼女に伝えて、一緒にディスカッションする。


例えば、ある会社が私と一緒にサービスを作りたいと持ちかけてきたとする。これに対して、私がどう考えたのかも彼女とディスカッションする。私のあらゆるビジネス上の決定をディスカッションしていると思ってもらっていい。


ペアシンキングによって、相手が何を考えているかわかるようになる。そして相手と信頼関係が築けるようになる。何考えているかわからない人とは、信頼関係築けないからね。


僕らはこんな感じで冒険を続けている。
このやり方が、あっているかどうかはわからないけれど、
毎日成長している実感がある。
昨日よりは、今日、少しはましなエンジニアになれた気がする。


一緒に成長できる仲間を持つことは素敵なことだよ。

おっさんへ(パロディ)

たまに「こいつはあの有名なxxxです」とおっさんを紹介される。
だいたい歳の頃は三十五歳以上、起業して経営者だったり、まあその背景は様々だ。
昨夜もそんな夜だった。


全く無関係な場所で、女子会をしていたら、「飲んでるから今からおいでよ」というお誘いが。僕は、たまに女子会に参加する。そのときには「やすえちゃん」と名乗っている。
このときには、仕方がないので、女子会が終わった後、いくことにした。


店に入ると数人のギョーカイもバラバラな、しかし知らない相手でもない人たちが囲炉裏を囲んでいた。
ほぼ貸し切り状態。


その日二度目となる夕食を僕は適当に楽しんでいた。夕食といっても、この手の付き合いのときには、酔っぱらわない必要最低限のものしか食べない。太るの嫌いだからね。
するとGoogleの某さんがつれてきた若者をおっさんが説教し始めた。まぁ、若者に厳しい話もしてあげた方がいいというGooglerの考慮らしい。


しばらく話を聞いていると今年の流行語大賞になるだろう言葉が発せられた。
「君からはコードの匂いがしない」


おっさんの説教は若者への愛があふれていた。いっていることは、自分の実体験に基づくものばかりだ。


しかし、おっさんの説教を聞いているうちに、自分の中の違和感は次第に大きくなり、ついに僕の口から不意にこんな言葉が出た。


「君(おっさん)、なにか危うくないか」


なぜ、そう感じたかというと説教の内容はすばらしいんだけど、全然その若者に響いている感じがしなかったからだ。だいたい、説教そのものが上の立場からするものなので、本当のことを言われたとしても、説教された人は、素直には受け入れがたいものだよね。説教って、一方向のやり取りだからどうしても伝わりにくい。


成功したおっさんがまさによく犯す間違いが、この「上から目線の説教」だと思う。いろんな成功を積み重ねているだけに、どうしても上の立場からの説教になってしまう。このような説教をする人を僕は「危うい」と感じる。


もし、若者に本気で何かを伝えたいと思うなら、やるべきことは、若者と同じ目線で向き合い、誠実に会話をすることではないだろうか。これは、何も若者に限った話ではない。目上の人にだってそう。誰かに本気で何かを伝えたいと思うなら、同じ目線で向き合い誠実に会話をした方がいいと思う。


こどもだってそうだよね。自分は大人、相手は子供みたいに接しても全然話をしてくれない。同じ目線で、同じ立場になって初めて心を開いてくれる。


うざいおっさんの話でも、おっさんが同じ目線で話してくれたら、もっと早くいいたいことが伝ったんじゃないかと思う。上から目線の説教で、人に何かを伝えるのは難しい。


僕は、説教なんていらないと思う。誰とでも、同じ目線で、誠実な気持ちで会話できれば、世の中は、居心地のいい場所になると思う。


あわせて読みたい
若人へ

残業をなくすためにすべきこと

残業を悪とするチームを作ろうのエントリに対して、質の良い仕事をするチームを作ったとしても、そのチームにほかから仕事がまわされて、結局残業は減らないんじゃないかという指摘をいただきました。


残業を悪とするチームを作るだけでは全く足りない


ご指摘の点はその通りだと思うのですが、自分のところは、残業を悪とするチームが作れているし、「結局日本じゃ残業が減ることはないよね」みたいな結論で終わりたくないので、「残業をなくすためにすべきこと」をしっかり指摘したいと思います。


まず、仕事を定時に終わらせる能力を持ったチームを作ったとしても、他から仕事がまわされて結局残業は減らないという点です。実際に良くおこりそうな話ですが、ここに問題が隠されています。


他から仕事がまわされてくるというのは、その仕事は、時間をかければ誰でもできる付加価値を生み出さない仕事だということです。正直言って、付加価値を生み出さない仕事をしている限りは、残業を減らすことはできません。
なぜなら、あなたは、誰でもできることを分担してこなす単なる労働リソースとしてしか、会社は見ていないので、できる限り働かそうとするからです。


ここで理解しておかないといけないことは、なぜ、上司は残業させるように仕向けてくるかです。残業をさせるとそれだけ費用がかかるため、会社としては、できるだけ社員を効率的に働かせ、残業はさせないようにするのが経済的なはずなのに。


一つ目の理由は、残業代が気にならないケースもあるということ。例えば、若い社員は、残業した分、残業代がかかりますが、残業代が安いので、残業させても大してコストは増えません。
また、ある程度年齢を重ねると裁量労働制になり、360協定にかからない程度で、できるだけ働かせた方が、会社としては得なのです。


二つ目の理由は、残業代がかかっても、上司にとってはそれが問題にならない仕組みが、会社に存在すること。
どういうことかというと、基本的に上司は、プロジェクトが完成することで評価されます。コストは二の次です。ここが問題。コストは二の次なので、部下/下請けをいくら働かせても良いから、プロジェクトを納期通りに完成させようとします。だから、残業をさせるように仕向けてくるのです。


デスマになったプロジェクトのマネージャーがよくがんばったと高い評価を得るのは、SIerでは良くある話です。これも上記の仕組が原因なのです。


コストは二の次といっても、コストが予算を上回ると、なぜなんだという追求は受けます。そのときに、きちんといい訳ができるようにするために、各工程で実際にどんな問題が起こったかの問題管理票を書かせ、それらに実際にどれくらい時間がかかったのかを正確につけさせようとします。後から、これだけ問題が起こり、これだけ時間がかかってしまったので、工数も膨らみましたが、自分はちゃんと管理してましたというためです。


上司にとっては、時間はかかってもいいんです。自分がちゃんと管理していることが証明できれば、コストがかかったことが自分のせいではなくなるので。
上司にとっては、起きたすべてのことが、問題管理票に書かれていることが重要です。自分がちゃんと管理していることを証明することだから。
問題が起きたときに、それを問題管理票(一般的にはチケット)だとかに書くことは大切です。ただ、起きたあらゆることを問題管理票に各必要はない。例えば、そういう上司は、レビューのときの誤字脱字まで、管理しようとするでしょう。本来問題でないことまで、すべて自分が管理していることを証明したいがために、部下や下請けに余分な作業をさせるのです。


これが、上司が残業を押し付けてくる良くあるパターン。理解できたでしょうか。
理解できたら次に必要なのは、こういう上司にどう対応したらいいか。


こういう上司は、自分のことしか考えていないことが多いので、あなたがどうがんばってもどうしようもありません。さっさとその上司から離れることに全力をつくすべきです。あきらめて残業をするのではなくてね。


上記の上司ほどダメ上司ではなく、部下/下請けのスキルがある程度評価できて、プロジェクトを効率よく進めたいと考えている上司がいるとします。このときには、どうしたらいいのでしょうか。


ちゃんとした上司であったとしても、あなたがが付加価値の低い仕事をしているなら、残業はさけられないでしょう。理不尽な残業は、押し付けられないと思いますが、社員の稼働率を上げるために、どうしてもオーバーワーク気味に仕事がくまれるためです。


こんなときに、あなたがとるべき行動は、付加価値の高い仕事をすることです。付加価値の高い仕事をしていれば、上司もそれを妨げるような付加価値の低い仕事をさせるようなことは基本しません。付加価値の高い仕事をさせていたほうが、会社の利益になるからね。


事実、私は、今やっているプロジェクトに集中していて、それ以外のことはいっさいやらないと会社や周りの人たちに宣言しています。周りの人も付加価値の高いことをしていると思っているから、それに集中することを認めている訳です。


私としても自分の価値は、付加価値の高い仕事をすることだと思っているので、集中力がないときや、頭の回転が悪いときに仕事をして、出来の悪い企画やソースコードが仕事の結果として残るのが怖い。だから、頭の回転が速いときにしか仕事をしません。


確かに、付加価値の高い仕事をし、それを周りにも認めてもらうということは、かなり難しいことですが、エンジニアとして成功したければ、くぐり抜けなければいけない関門です。


「結局日本じゃ残業が減ることはないよね」みたいな結論で終わりたくない。きちんと努力して自分を磨き、付加価値の高い仕事ができるようになれば、残業を減らすことができる。そのように、前向きに生きていきたいと思っています。

残業を悪とするチームを作ろう

長時間労働サービス残業は、基本的には会社の問題であり、上司の問題です。
例えば、大手SIer長時間労働サービス残業が発生するよくあるケースを見てみましょう。


会社は、ワークライフバランスを向上させるために、年間360時間以上の残業をしてはいけないというルールを決めたとします。この段階で、会社は残業は社員のために良くないと認識しています。


現場は、社員の稼働率を上げるためにオーバーワーク気味に仕事をアサインします。仕事がないときに備えて、仕事があるときは、多めに仕事を振るのです。これが間違いなのですが、たいていの現場は、このように行動してるでしょう。つまり、仕事があるときは、多めに振られているので残業することが前提なのです。


ここで、会社の作った残業規制のルールが効いてきます。上司は、会社のルールがあるので、月30時間以上の残業をつけることを基本禁止します。「残業をつけることを禁止する」だけで残業そのものを禁止している訳でないことがポイント。
残業を禁止するとプロジェクトが遅れることがわかっているから、残業そのものは禁止しない訳です。これがずるい。


そういわれた社員は、30時間以上の残業はつけなくなるでしょう。これが、ザビ残が発生する典型的な例。
会社は、社員の残業を減らしたいと思ってルールを作ったのに、残業は減らず、ザビ残を発生させる原因を作ってしまったのです。


残業の問題を会社や上司のせいにしても実は何も解決しません。会社や上司を変えることは、とても難しいことだからです。


この問題を解決するには、自分たちのチームを作るのがおすすめ。会社や上司を変えることは難しいけど、仕事上のチームを作ってその中は残業を悪とする文化にすれば良い。


残業を悪とする文化にするには、残業をしてもプロジェクトのためにならないことをチームのメンバー全員が理解していることが必要です。残業することによって、プロジェクトが良い方向に進むと思うなら、無理して残業する人が出てきてしまうからです。
残業を悪とするチームを作ったとしても、そのチークの成果が以前より下がってしまったら、上司から圧力がかかり、残業を悪とするチームを維持できないでしょう。チームを維持するためには、生産性も向上させる必要があります。


どうすれば残業を悪と見なし、チームの生産性を向上させることができるのでしょうか。
それは、チームの全員が仕事の質に誇りを持つことです。
仕事の質に誇りを持つなら、長時間残業はできません。なぜなら、長時間残業すると仕事の質が落ちることは、だれでもわかるからです。


これまでは、仕事の質にこだわらず、とりあえず仕事を進捗させるために残業をしていたのではないかと思います。仕事の質が悪いから、仕事の効率も悪いのです。
だったら、仕事の質にこだわりましょう。そうすると残業ができなくなる。仕事の質が高いから、チームの生産性も上がり、以前よりもプロジェクトを早く前に進めることができるようになる。


仕事の質に誇りを持ち、残業を悪とするチームを作ることは、あなたにもできます。


私のチームは、ペアプロで仕事をしているので、マジに長時間の仕事はできません。ペアプロはものすごく集中しないとできないから。それが逆に残業を悪とする文化を作れているのかもしれません。
ルールは状況によって変えているけど、最新の仕事のルールは、夜20時以降は作業をしないことです。起きて13時間以上たつと効率が落ちるというルールがあるらしいので、7時におきたら夜20時以降は作業しないというのは理にかなってますね。


あわせてよみたい。
長時間労働・サービス残業は自分の価値を下げ企業存続を危うくする
残業をしない会社を作るために