SSTエンジニアブログ

SSTのエンジニアによるWebセキュリティの技術を中心としたエンジニアブログです。

Spring Fest '19 参加レポート

こんにちは、SSTでWeb脆弱性診断用のツール(スキャンツール)開発をしている坂本(Twitter, GitHub)です。

2019-12-18 (水) に御茶ノ水ソラシティで開催された Spring Fest '19 に参加してきましたので、聴講したセッションの感想や講演資料のリンクなどをまとめます。

ここ1-2年の間に自分の中で Spring エコシステムへの興味と関心が高まっており、最新の Spring エコシステムの動向に触れたり、盛り上がりを体感するため 1日使って基調講演 + 7セッションを聴講してきた次第です。

なおセッションについては複数ホールで同時並行で開催されていました。 坂本の身は一つのため、涙をのんで聴講を諦めたセッションもあります。 Twitterのhashタグ #jsug を追えば、登壇者からの講演資料や参加者のリアルタイムのつぶやきが見れますので、参加できなかったセッションについてはそちらで後日チェックしたいと思います。

基調講演 + 各セッションの概要と感想

それでは基調講演 + 坂本が聴講した各セッションの概要や感想を紹介します。 (もし間違いなどありましたらご指摘ください)

基調講演 : From Spring Boot 2.2 to Spring Boot 2.3

Pivotal の Toshiaki Maki, Stéphane Nicoll のお二人から、2019年までの振り返りと今後について発表がありました。

振り返りとしては次の2点が印象に残りました。

  • RSocket 対応
    • 午後のセッションでも詳細な紹介がありましたが、TCP/WebSocket/UDP/HTTP2 上で Reactive Stream のセマンティクスを扱える RSocket プロトコルに対応し、WebFlux と組み合わせた reactive プログラミングの広がりを実感しました。
  • R2DBC 対応
    • 非同期処理で今まで悩ましかったのが blocking I/O であるJDBCの扱いでした。これを解決するために R2DBC が開発され、Spring でもサポートが始まったようです。

今後については、GraalVM Native Image のサポートが Spring Framework 5.3 で本格対応される予定、というのが楽しみです。 これについては他のセッションでも詳しく紹介されており、坂本も聴講してきましたので後ほど紹介します。

サムライズム Spring Boot 爆速開発超絶技巧

株式会社サムライズムの 山本裕介 さんから、IntelliJ IDEA で爆速開発するためのショートカット技法の紹介でした。

タイトルに惹かれてセッションに参加したものの、坂本自身は諸々の理由で Eclipse ユーザだったこともあり「失敗したかな・・・」と思ったのも一瞬のことで、目の前で繰り出される数々のショートカットによる爆速操作を目の当たりにし、「IntelliJ IDEAに乗り換えようかな・・・」と若干ながら心が傾いたことをここに告白します。

他にも IntelliJ IDEA の機能で心を動かされたのは以下のような機能です。Eclipse/STSでも使えないものか・・・。

  • 条件付きブレークポイント簡単に使える。
  • 「ログを出力するだけ」なブレークポイントも設定できる(printデバッグ不要)
  • docker連携で、コンテナ内のファイル一覧を参照することもできるようになった。便利そう。
  • Spring Boot プロジェクトで Actuator を入れてると Actuator のエンドポイント一覧を表示してくれたり、URL path mapping 一覧も見れる。これも便利そう。

最後に、デモで使われてたIntelliJ IDEA ではプログレスバーが猫アイコンで可愛く表示されてたのがほっこりしました。 Nyan Progress Bar プラグインみたいです。

LINE公式アカウントのチャットシステムにおける Spring および WebFlux の活用事例

LINE の Ryosuke Hasebe さんから WebFlux でリアルタイムなチャットシステムを構築した事例とノウハウの紹介でした。

自分では Spring WebMVC しか使ったことがなく、最近のドキュメントでよく見かける WebFlux ってなんだろうと気になってたところにちょうどこのセッションがあり聴講してみた次第で、大変勉強になりました。 チャットシステムでは Server-Sent Event : SSE をWebFlux と組み合わせていて、「SSEは長時間Eventが無いと接続が切れるので、定期的にpingを送るようなFluxも作った」というお話も勉強になりました。 チャットで送信された音声・画像・動画などの取得で、認証システムにあわせて認証を肩代わりする non-blocking なプロキシを WebFlux で作ったというお話も、実際に Netty ベースでプロキシを作ったことのある身としては激しくうなずけます。 ストリーミングメディアを扱うユースケースにも向いてると感じました。

スキャンツール開発を考えると、実は SSE など非同期レスポンスの扱いは悩ましい問題です。 というのも、Webアプリのブラックボックステストを行うスキャンツールでは1リクエストを送信して、レスポンスを受信しきってからその内容をチェックするというのがオーソドックスな動きです。 ところがレスポンスの受信がいつ完了するのか分からない非同期な性質があると、いつレスポンスデータをチェックすればよいのか?チェックし終わったと言えるのはいつなのか?という問題が出てきます。 さらに、そもそもリクエストとレスポンスがペアにならない = 攻撃パターンの入力ソースとタイミングが、レスポンスと1:1にならないという問題も考慮しないといけません。

チャットシステムの非同期レスポンスを例にすると、リクエストはあくまでも「非同期レスポンスを受信開始したい」というリクエストであり、レスポンスの内容とは無関係です。 システム上の別の入り口(イベントソース)からのメッセージが来て、始めてレスポンスにメッセージが表示され、そこからXSSなどの脆弱性が生じると考えることができます。 つまり反射型の脆弱性よりは、蓄積型の脆弱性の検査が主軸となるように思われます。 さらには、そうした非同期レスポンスを扱うクライアント側は当然、ブラウザ上のJavaScriptやデスクトップ/スマホアプリとなるでしょう。 つまり API として扱うことになり、脆弱性の検査観点も考慮が必要となります。 こうした問題は、非同期レスポンスを適切に扱うことの技術的な難しさと合わさり、今後のスキャンツール開発(Webアプリのブラックボックステストツール)や脆弱性診断での課題になりそうだなと感じました。

進藤 遼 実践 Spring Boot Actuator + Micrometer

進藤さんが体調不良で、急遽 Tommy Ludwig さんによる Spring Boot Actuator + Micrometer の紹介となりました。

Actuator 自体は色々情報が取れて便利だな~と前から思ってましたが、それを実際のメトリクス監視でどう活用するのか気になってました。 また Micrometer は名前すら知らなかったレベルで、初心者モードでセッションを聴講してみた次第です。 運用監視などで使うメトリクス(CPU使用率とか、アプリ独自のパフォーマンス指標など)のロガーみたいなもののようです。 ロガーなのでアプリに組み込んで使い、ログの宛先としては Datadog や Prometheus などメジャーな運用監視システム毎にドライバが用意されているようです。

Spring Boot Actuator では /metrics endpoint で Micrometer を使っていて、以下のようなメトリクスを収集できるよう予め設定済みだそうです。

  • HTTP server, client 系のメトリクス
  • JVMメトリクス
  • Thread の Executors
  • HikariCP, MongoDB, Kafka, RabbitMQ, Redis などのデータ系

運用監視との連携についても、設定ファイルを少しいじるだけで簡単に ElasticSearch にメトリクスログを送って、Kibana でダッシュボードを表示するデモが紹介され、便利そうでした。

感想ですが、メトリクスを取得する対象がOSからアプリケーションに、また取得するプロトコルもHTTPなどWeb系に移ってるんだな、と実感しました。 今までの自分の中のイメージだと、サーバOSにメトリクス監視用のエージェントを入れて、その中でOS全体 + アプリケーション固有のプロセス死活監視などで監視するイメージでした。 しかしクラウドやコンテナ全盛の時代において「OSにエージェントを入れる」というのがそもそも使えない状況も増えてきており、アプリケーション自身がメトリクスを扱うほうがコンテナやサーバレス環境では便利なのかもしれません。 またプロトコルについても、Javaの場合JMXがありますが基本的にはJava - Java 間の通信となります。一方で Spring Boot Actuator ではHTTPエンドポイント + JSON というWebベースのプロトコルなので、Web技術をベースとしたモダンな運用監視システムと親和性が高いように感じました。

岩塚 卓弥 Spring と GraalVM Native Image - 2019/12

NTTソフトウェアイノベーションセンタの岩塚 卓弥 さんから、Spring Framework における GraalVM Native Image 対応状況のこれまでと今後についての紹介です。

Spring アプリを事前コンパイルして爆速起動したら便利そうだけど、今のサポートはどんな感じかな?と聴講してみました。 デモで Hello, World のNative Image生成(AOTコンパイル) が数分かかり、Spring Boot アプリのサンプルに至っては事前検証時に50分かかったという話があり、これはさすがに長すぎるな・・・という印象でした。 また事前コンパイルのデメリットとして、最適化に限界がある点も紹介されていました。実行時の Hotspot を考慮したJITコンパイルの方がGraalVM Native Imageよりも高速という検証結果も紹介されており、サーバサイドで Native Image を使うのはデメリットばかりが目立ってしまうように感じました。

サーバサイドよりは、CLIツールやちょっとしたデスクトップアプリの方が Native Image に向いているように思います。 ユーザの手元で何回も素早く起動してくれて、しかもJITコンパイルに必要なHotspot解析が不要なくらい実行時間が短ければ、Native Image のメリットを活かしつつデメリットを感じずに済むことができそうです。 またネイティブ実行可能なバイナリにパッケージングできるので、クライアントアプリケーションとしての配布にも最適です。

自分としてはJavaでツールを作る場合のパッケージングや配布の選択肢の一つとして、GraalVM Native Image のビルドを考えていきたいと思います。

槙 俊明 RSocket徹底入門 Spring 5.2の 目玉機能であるRSocket対応とは

Pivotal の Toshiaki Maki さんから RSocket と Spring での対応についての紹介です。

RSocketは双方向・多重通信が可能なバイナリプロトコルで、 TCP/WebSocket/UDP/HTTP2 に載るアプリケーションレイヤーのプロトコルだそうです。 Reactive Foundation で開発されていることもあり、Reactive Stream の pub-sub 方式で流量制限 (Back Pressure) が使えるとのこと。 ブラウザ上のJSとサーバサイド間で、WebSocketの上でRSocket通信できるのが面白かったです。 Spring Boot 2.2 での対応では TCP と WebSocket をサポートするとのことなので、ブラウザJSとサーバサイドSpringアプリをWebSocket + RSocketで連携させる、というのが面白そうです。

当面はごく限られたユースケースでしか使われないと思いますが、診断で遭遇したらかなり扱いが難しそうに感じました。 WebFluxのセッションで非同期レスポンスの難しさについて書きましたが、こちらはリクエストについても非同期に細切れで送ることができるのと、そもそも HTTP 上にそのまま乗らないプロトコルです。 そのため疑似攻撃パターンを送るためにはおそらく専用ツールを作るしかなく、それもアプリケーションの特性に合わせてメッセージ内容も非同期で送る必要があります。 メッセージの中身も、おそらくアプリ固有のデータをシリアライズしたバイナリデータになることから、疑似攻撃パターンの埋め込みも苦労しそうです。

とはいえ、ある程度のプログラミング技術があればやってできないことは無いと思います。 今回のセッション聴講をきっかけに、RSocketの診断依頼が来ても最善を尽くせるよう、勉強を積み重ねていきたいと感じました。

楽天 Spring Social でソーシャルログインを実装する

楽天ペイの 田中 竜介 さんから、Spring Security OAuth を使ったソーシャルログインの解説です。

セッションタイトルでは Spring Social とありますが、すでにEOLになっており、OAuth を使うよう移行が推奨されているようです。 そのためセッション内容も Spring Security OAuth を使ったソーシャルログインの紹介でした。

デモでは簡単なコードと設定だけで、Facebook / Google でログインできる様子が紹介されました。Google / Facebook / GitHub / Okta については Spring Security OAuth の方で認可サーバのURLなど含んでいて、クライアントIDやシークレットを設定するだけでそのまま動かせるのは大変便利そうでした。

とはいえ Spring Security OAuth はクライアント側のライブラリであり、認可サーバやリソースサーバ側での実装まではカバーしていないようです。 またクライアント側の処理についてもデフォルトで対応していないカスタムのソーシャルログインにどう対応させるか、カスタマイズするとなると結構苦労しそうな印象を受けました。

ソーシャルログインを使うサイトの診断依頼も増えている昨今、Springにおける認証・認可のベストプラクティスとして Spring Security OAuth の知識を深めていければと感じました。

ウルシステムズ 大規模基幹システムにSpring Cloudを使いたい!

ウルシステムズ株式会社 の 黒川 徳介 さんから、大規模基幹システムに Spring Cloud を導入する、ひいてはマイクロサービスを導入するときの課題と解決方法についての紹介です。 Spring Cloud は今まで全く知らなかったのですが、マイクロサービスをコアとして分散アーキテクチャを実現するためのサービスやツール群を提供しているようです。 イメージ的には、Spring Cloud のコンポーネントを上手く組み合わせることでちょっとした専用クラウド/マネージドサービスを組み立てられる、という感じでしょうか。

セッションでは Spring Cloud そのものよりは、マイクロサービス導入時の障害となる組織/開発/運用の諸問題をどうクリアしていくかにフォーカスしていました。 一方で診断サービス提供観点でマイクロサービスを考えてみると、真っ先に思い浮かんだ感想が「診断環境の構築が大変になりそうだなぁ」でした。 診断では予期せぬ障害や高負荷が発生しうるため、可能であれば診断専用のサーバ環境の立ち上げをお願いすることがあります。 古典的な Web - AP - DB サーバ構成でも1セットの用意が大変なのに、マイクロサービスを活用して複数のアプリケーションやDBが連動し、負荷に連動したスケールアップのための監視システムやインスタンス管理まで渾然一体となったシステムを「診断用にもう1セット用意して」というのは相当な作業負荷が想像できます。 この点は今後の診断前の調整に考慮していければと思います。

聴講しなかったセッションの資料

同時開催していたセッションなどで、やむなく聴講を見送ったセッションの講演資料がTwitterで公開されていましたので、個人的に行きたかったセッションに絞ってまとめておきます。

Qiitaでも他の参加者がまとめ記事を公開されていました。こちらもご覧ください。

全体的な感想

国内Java開発で Spring エコシステムが十分に受け入れられている様子を実感できました。 今ならJavaのWeb開発で「とりあえず Springで」作っても問題ない状況と思われます。

DDD / マイクロサービス / TDD など開発プロセスや思想に関わる発表も多く、もちろんこうしたイベントに登壇するようなところなのでバイアスもあるでしょうが、ずいぶん進んでるなという印象もありました。 また RSocket や WebFlux など 非同期 / reactive なパラダイムでの通信プロトコルやアーキテクチャも浸透しつつあり、今後は reactive をきちんと押さえておかないと、いざ開発者と会話したときについていけないかも・・・という一抹の不安も感じました。この辺、ラムダ計算とか関数型プログラミングのパラダイムがベースになっているように感じており、少しずつ勉強中だったりします。

今回得られた知見やノウハウを元に、より良い診断サービスやスキャンツールの開発につなげて行きたいと思います。

Spring Fest '19 を主催した JSUG のみなさん・登壇者のみなさん、ありがとうございました!