Upgrade to Pro — share decks privately, control downloads, hide ads and more …

チャットディーラーの高速開発を支えるLaravel / laraveljpcon ChatD...

坂田晃平
February 16, 2019

チャットディーラーの高速開発を支えるLaravel / laraveljpcon ChatDealer Rapid Development with Laravel

坂田晃平

February 16, 2019
Tweet

More Decks by 坂田晃平

Other Decks in Technology

Transcript

  1. 自己紹介 • 名前:坂田 晃平 • 所属:株式会社ラクス – メールディーラーと チャットディーラーの開発を担当 •

    経歴: – 2016 年 新卒入社(3 年目) – PHP の使用歴も 3 年目 • メールディーラー :ノンフレームワーク • チャットディーラー:Laravel 1
  2. • はじめに • チャットディーラー(ChatDealer)とは • なぜ Laravel を選択したか? • Laravel

    で良かったこと • Laravel で困ったこと • まとめ 今日話すこと 3
  3. 10 年以上 PHP でノンフレームワークで開発・運用されてきた主力サービ ス(メールディーラー)の開発チームが、新規に姉妹サービス(チャット ディーラー)を立ち上げる際に Laravel を選択をしました。 開発期間半年というスピードが求められる中で、チームが Laravel

    に抱い た理想と現実、また、Laravel (Blade) と Vue.js の組み合わせにより発生 した脆弱性への対応など、Laravel での新規サービス立ち上げの経験を具 体的にお伝えします。 <セッション概要>より 5
  4. • 2001 年にサービス提供開始 • 4,000 社以上の導入実績 • メール共有・管理システム市場で 9 年連続

    シェア No.1 • PHP でノンフレームワークで開発 8 メールディーラー(MailDealer)とは
  5. • PHP 4 時代にサービスの土台を開発 (参考) PHP 4.0 リリースが 2000/05/22 •

    長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない – リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下 9 課題
  6. • PHP 4 時代にサービスの土台を開発 (参考) PHP 4.0 リリースが 2000/05/22 •

    長期間改修されてきたソースコード – ソースコードの構成が機能ごとにちぐはぐ – ビューとロジックが分離されていない – リクエストパラメータの受け渡しが煩雑 – バリデーションが煩雑 – etc… • メンテナンス性の低下 10 課題 課題感をもつ開発チームが 新サービスを立ち上げ!
  7. 技術スタック • 言語、フレームワーク – PHP 7.1、Laravel 5.5 – Node.js、Express、Socket.IO •

    開発環境 – PhpStorm、Jenkins、Redmine、GitLab、 Mattermost • インフラ – 仮想基盤(オンプレ)、nginx、Apache、 PostgreSQL 9.6、Redis 14
  8. はじめに • 新サービスの立ち上げに際しての課題 – 短納期(6 ヶ月) • 実装の期間は実質 2 ヶ月

    • 開発効率の向上必須 – レガシーからの脱却 • レガシーシステムの課題を解決 • 開発チームはフレームワークを使っていない 17
  9. 開発スケジュール 18 2月 3月 4月 5月 6月 7月 要件定義 2017年

    開発基盤整備 設計 実装・単体テスト システム テスト β版フィード バック改修 β版リリース 本番リリース
  10. はじめに • 新サービスの立ち上げに際しての課題 – 短納期(6 ヶ月) • 実装の期間は実質 2 ヶ月

    • 開発効率の向上必須 – レガシーからの脱却 • レガシーシステムの課題を解決 • 開発チームはフレームワークを使っていない 19
  11. • 実装工数の短縮 • メンテナンス性の向上 – MVC モデルによるコードの分離 – コーディングルールやファイル構成の標準化 –

    リクエスト情報の管理方法の標準化 – 一般的な脆弱性への対策 21 フレームワークに期待すること
  12. 選定条件:長期サポート • Laravel は LTS に対応 – Laravel 5.1 より

    LTS に対応 – バグフィックスは 2 年間 – セキュリティーパッチ提供は 3 年間 – 新サービス開発開始の半年後に新たな LTS バー ジョン (5.5) がリリース予定 26
  13. Laravel で良かったこと • Laravelを使えば… – ルーティングはデフォルトの仕組みを使おう – Middleware で共通処理をやろう –

    Request クラスにルールを書こう – ロジックは Service クラス、ビューは Blade で – Config で設定して後はクエリビルダで DB 使おう – etc 34
  14. Laravel で良かったこと • Laravelを使えば… – ルーティングはデフォルトの仕組みを使おう – Middleware で共通処理をやろう –

    Request クラスにルールを書こう – ロジックは Service クラス、ビューは Blade で – Config で設定して後はクエリビルダで DB 使おう – etc 35 フレームワークってこんなに便利なんだ
  15. Blade + Vue.js での脆弱性 • Laravel 標準の認証画面に XSS の問題 –

    ある時のリリースノート > In Laravel 5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. > Laravel 5.6.9 と 5.5.37 では、標準のスキャフォール > ディングで、潜在的な XSS の可能性が修正されました。 https://laravel-news.com/laravel-5-6-9 39
  16. • Laravel 標準の認証画面に XSS の問題 – ある時のリリースノート > In Laravel

    5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. Laravel 5.6.9 と 5.5.37 では、標準のスキャフォールディ ングで、潜在的な XSS の可能性が修正されました Blade + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 40 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ?
  17. • Laravel 標準の認証画面に XSS の問題 – ある時のリリースノート > In Laravel

    5.6.9 and Laravel 5.5.37, a potential XSS > vector was patched in the default Bootstrap > scaffolding that ships with laravel. Laravel 5.6.9 と 5.5.37 では、標準のスキャフォールディ ングで、潜在的な XSS の可能性が修正されました Blade + Vue.js での脆弱性 https://laravel-news.com/laravel-5-6-9 41 XSS なんて怖いわぁ…。 標準のスキャフォールディングは使っ てないし関係ないっぽいけど。 でも、どこで XSS になってるんやろ? 実は、、、関係あった! (調べてよかった…)
  18. Blade + Vue.js での脆弱性 • サーバーサイドでのHTML構築と Vue.js との組み合わせで起こりうる XSS –

    Blade との組み合わせに限らない – 実は Vue.js 特有というわけでもない • AngulerJS ではもっと前(2014 年くらい)から話題 になっていたらしい https://havelog.ayumusato.com/develop/security/e593- mixins_server_template_and_angular.html 42
  19. • Bladeと Vue.js の組み合わせで起こる XSS サーバーでの処理 ブラウザでの処理 Blade + Vue.js

    での脆弱性 <div id="app"> {{ $name }} </div> sample.blade.php Blade で処理 $name = “{{ alert(‘XSS') }}” <div id="app"> {{ alert(&apos;XSS&apos;) }} </div> <div id="app"> {{ alert(‘XSS’) }} </div> Vue.js が処理 <div id="app"> </div> 43 {{ … }} の中の スクリプトが実行 される! 処理済みのHTMLデータ レスポンス送信 ブラウザが読込
  20. • Bladeと Vue.js の組み合わせで起こる XSS サーバーでの処理 ブラウザでの処理 Blade + Vue.js

    での脆弱性 <div id="app"> {{ $name }} </div> sample.blade.php Blade で処理 $name = “{{ alert(‘XSS') }}” <div id="app"> {{ alert(&apos;XSS&apos;) }} </div> <div id="app"> {{ alert(‘XSS’) }} </div> Vue.js が処理 <div id="app"> </div> 44 {{ … }} の中の スクリプトが実行 される! 処理済みのHTMLデータ レスポンス送信 ブラウザが読込
  21. • Blade と Vue.js の組み合わせで起こる XSS – Vue.js で処理される領域にユーザー入力の文字 列をサーバー処理で埋め込むと危険

    – “mustache injection” と(個人的に)呼んで る {{…}} ← これを Mustache 構文と呼ぶことから – 知らなかったら普通に作ってしまいそう Blade + Vue.js での脆弱性 45
  22. • Blade と Vue.js の組み合わせで起こる XSS – Vue.js で処理される領域にユーザー入力の文字 列をサーバー処理で埋め込むと危険

    – “mustache injection” と(個人的に)呼んで る {{…}} ← これを Mustache 構文と呼ぶことから – 知らなかったら普通に作ってしまいそう Blade + Vue.js での脆弱性 46 知らなかったし、 実際作ってしまっていた
  23. Blade + Vue.js での脆弱性 • mustache injection 対策案1 (不採用) –

    “{” や “}” を HTML エスケープ • 効果なし サーバー側でエスケープしても、Vue.js が処理する 時にはブラウザによってもとに戻されてしまっている 47 サーバーでの処理 <div id="app"> &#123;&#123; alert(&apos;XSS&apos;) &#125;&#125; </div> <div id="app"> {{ escapeMustache($name) }} </div> sample2.blade.php ブラウザでの処理 <div id="app"> {{ alert(‘XSS’) }} </div> $name = “{{ alert(‘XSS') }}”
  24. Blade + Vue.js での脆弱性 • mustache injection 対策案2 (不採用) –

    “v-pre” ディレクティブの利用 • Laravel のスキャフォールディングでの対策 • 効果は実証されている • 結果:対象箇所が多すぎる・新しく書く時も必ずつけ る必要・忘れそう 48 ブラウザでの処理 <div id="app"> <span v-pre>{{ alert(‘XSS’) }}</span> </div> v-pre の要素内は Vue.js で処理されない
  25. Blade + Vue.js での脆弱性 • mustache injection 対策案3 (採用) –

    “{{” や “}}” の文字間に半角空白を挿入する • “{” や “}” のHTMLエンティティ表現に対しても同様 に処理が必要 ↓ • “{”、“&#123;”、“&#x7b;” のうち 2 つの組み合わせ • “}”、“&#125;”、“&#x7d;” のうち 2 つの組み合わせ • さらにそれらが連続している場合でも漏れなく空白を 入れる必要がある 49 サーバーでの処理 {&#123;{&#x7b{ … }&#x7d}&#125;} 危険な文字列: { &#123; { &#x7b; { … } &#x7d; } &#125; } 無害な文字列:
  26. Blade (SSR) + Vue.js での脆弱性 • mustache injection 対策案 (3)

    – “{{” や “}}” の文字間に半角空白を挿入する • “{” や “}” のエンティティ表現に対しても同様に処理 が必要 ↓ • “{”、“&#123;”、“&#x7b;” のうち 2 つの組み合わせ • “}”、“&#125;”、“&#x7d;” のうち 2 つの組み合わせ • さらにそれらが連続している場合でも漏れなく空白を 入れる必要がある 50 サーバーでの処理 {&#123;{&#x7b{ … }&#x7d}&#125;} 危険な文字列: { &#123; { &#x7b; { … } &#x7d; } &#125; } 無害な文字列: $replacementMap = [ "{{" => "{ {" , "{&#123;" => "{ &#123;" , "{&#x7b;" => "{ &#x7b;" , "&#123;&#123;" => "&#123; &#123;" , "&#123;{" => "&#123; {" , "&#123;&#x7b;" => "&#123; &#x7b;" , "&#x7b;&#x7b;" => "&#x7b; &#x7b;" , "&#x7b;{" => "&#x7b; {" , "&#x7b;&#123;" => "&#x7b; &#123;" , "}}" => "} }" , "}&#125;" => "} &#125;" , "}&#x7d;" => "} &#x7d;" , "&#125;&#125;" => "&#125; &#125;" , "&#125;}" => "&#125; }" , "&#125;&#x7d;" => "&#125; &#x7d;" , "&#x7d;&#x7d;" => "&#x7d; &#x7d;" , "&#x7d;}" => "&#x7d; }" , "&#x7d;&#125;" => "&#x7d; &#125;" ];
  27. Blade + Vue.js での脆弱性 • mustache injection 対策案3 (採用) –

    “{{” や “}}” の文字間に半角空白を挿入する – いつやるか? • 出力時 ⇒ “v-pre” 使用と同様の問題。対象箇所が多い・忘れ そう • 入力時 ⇒ Middleware ですべてのリクエストパラメータを処 理すれば確実 – 根本的な解決は…(^ω^; • Blade と Vue の完全分離しかない? 51
  28. Vue.js は思ったより難しかった 53 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン)

    – Vue.js は「学習コストが低い」という前評判 – 軽く公式のガイドを見てもそんな印象
  29. Vue.js は思ったより難しかった 54 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン)

    – Vue.js は「学習コストが低い」という前評判 – 軽く公式のガイドを見てもそんな印象 タグに`v-bind:`ってつ ければモデルの値が表示 される! モデルの値を変えたら自 動で反映される! 便利!簡単そう! (と思ってしまった)
  30. Vue.js は思ったより難しかった 55 • 開発を始める前は… – チームメンバーはみな jQuery に慣れ親しんで いる(特にベテラン)

    – Vue.js は「学習コストが低い」という前評判 – 軽く公式のガイドを見てもそんな印象 タグに`v-bind:`ってつ ければモデルの値が表示 される! モデルの値を変えたら自 動で反映される! 便利!簡単そう! (と思ってしまった) そのまま開発に突入
  31. Vue.js は思ったより難しかった 56 • 開発を始めてみると… Vue インスタンス入れ子 にしたいんだけど… Vueインスタンスって 飛び地にできないの?

    モデルの値を変えてるは ずなのに反映されない… Bootstrap一緒に使いた いけどうまくいかない…
  32. Vue.js は思ったより難しかった 57 • 開発を始めてみると… いったいどうすればいいの…? Vue インスタンス入れ子 にしたいんだけど… Vueインスタンスって

    飛び地にできないの? モデルの値を変えてるは ずなのに反映されない… Bootstrap一緒に使いた いけどうまくいかない…
  33. Vue.js は思ったより難しかった 62 • jQuery 脳からのパラダイムシフトが必要? – 「jQuery でなら作り方わかってるのに」 –

    利き手でない方の手で字を書くかのよう… – 結局慣れるしかない • jQuery 系ライブラリとの相性 – ノウハウの蓄積が必要
  34. Vue.js は思ったより難しかった 63 • やっぱりちゃんと勉強しないとだめだった – 学習資料も限られていた – 最近は充実してきている •

    コンポーネントの理解は必須 – 分かりにくいとの声もあるが – そこは勉強してもらうしかない
  35. まとめ • フレームワークがスピード開発に役立った – ミドルウェアとの連携設定 – MVC の考えに沿ったソース配置 – ビジネスロジックへの集中ができた!

    • とくに Laravel で良かったこと – 豊富な機能 – 日本語公式ドキュメント – 活発なコミュニティ • 脆弱性への対応も早かった 65