GMO Flatt Security Blog

GMO Flatt Security株式会社の公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

GMO Flatt Security株式会社の公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

登壇・ハンズオン主催・聴講・ブース出展・運営スタッフ...... それぞれのTSKaigi 2025

こんにちは、"エンジニアの背中を預かる" をミッションに掲げるGMO Flatt Security(以下、Flatt)です。

弊社はそのミッションの通り開発組織にとって体験の良いセキュリティサービスを提供しており、その関係で技術コミュニティに協賛・カンファレンスにブースを出展させていただく機会が比較的多いです。今回、5月に開催されたTSKaigi 2025に関しても例に漏れず協賛させていただいたのですが、TSKaigi 2025では通常の協賛枠にとどまらず、公認サイドイベントを開催したり、CFPを通過し登壇する社員がいたり、カンファレンス自体の運営に携わっている社員がいたり、業務としてセッション聴講に参加した社員がいたりと、多彩な関わりが生まれました。

本記事では、各メンバーから寄稿してもらい、Flattという技術組織がどのようにTSKaigi 2025の盛り上がりの一端を担わせていただいたか、お伝えしようと思います。

公認サイドイベント「はじめての静的解析」 by pizzacat83

TSKaigi の公認サイドイベント「はじめての静的解析」の講師を務めた pizzacat83 です。

このイベントでは、「自分たちのコードベースに特化したコーディング規約を custom lint rule として表現し、自動検査可能にする」を目標に、ast-grep のルールを自作するハンズオンを行いました。 ハンズオン資料は以下のリポジトリで公開しています。

近頃 AI による自律的なソフトウェア開発の能力が飛躍的に向上しており、人間だけでは不可能なペースでコードを書くことが可能になりました。これに伴い、プロダクト開発のボトルネックは、「AI が書いたコードがマージ可能な品質か」を保証するプロセスに移りつつあると、私は開発者の一人として日々痛感しています。

TSKaigi でも、本記事で後ほど xryuseix さんが解説する Yuku Kotani さんのセッション「AI Coding Agent Enablement in TypeScript」において、AI Agent を自走させるための静的解析の有用性が語られていました。この潮流は、我々 Flatt が3月にリリースしたセキュリティ診断 AI Agent「Takumi」とも通じるものです。Takumi は古典的な静的解析ではなく AI による自律的なコード調査ではあるものの、AI 時代のソフトウェア開発のスピードに追従する継続的なセキュリティレビューを実現するという点で、共通の課題にアプローチするものです。

ハンズオンでは Next.js アプリケーションを題材に、「権限チェック処理を忘れているリクエストハンドラがないか」を検査するカスタムルール作成に取り組みました。このお題を選んだ背景は、認可制御の不備が現代の Web アプリケーションにおける最大のリスクだという私たちの認識があります。

認可制御の不備はセキュリティ領域の国際的な調査リポート「OWASP Top 10」の最新版にて第1位のリスクとして挙げられています。我々 Flatt が提供するセキュリティ診断サービスにおいても、これまで報告してきた脆弱性の中でも最も多く検出されてきたカテゴリです1

しかし認可制御のモデルやその実装はアプリケーションごとに異なることから、言語やフレームワークの標準機能、linter のデフォルトルールだけで認可制御の不備は防げないことがほとんどです。SQL injection のような典型的な脆弱性に対してはフレームワーク側での対策が進んでいる現代において、認可制御不備が最大のリスクである所以がここにあります。だからこそ、個々のアプリケーションに特化したカスタム静的解析ルールによって認可制御不備を防ぐことが有効だと考えています。

TypeScript で静的解析といえば ESLint, Biome などが代表的ですが、このハンズオンでは ast-grep というツール向けのカスタムルールを作成しました。この選択は、「はじめての 静的解析」というコンセプトに基づくものです。

どのツールを使うにしろ、やることは「この条件を満たすコード片は禁止する」という条件を言語化することです。より詳細には、「コードの構文木の部分木を入力として、禁止するかを判定する」判断ロジックを実装することになります。ここで重要となるのは、コードを構文木として捉えるメンタルモデルです。ast-grep のルールは ESLint と異なり、検出したい構文木の条件を宣言的に記述するものであることから、はじめての人でも比較的取り組みやすいと考え題材としました。(Biome のカスタムルールも同様に宣言的ですが、ast-grep の playground がとても直感的で分かりやすく、かつ環境構築不要でブラウザから試せることもハンズオンでの採用理由の一つです。)

ast-grep playground。左上が解析対象のソースコード、左下がその構文木。右側パネルに入力したカスタムルールは、まさに構文木の条件を宣言的に記述したものである

参加者の方からは「明日から使ってみたい」といった嬉しい声も聞かれ、実践に繋げられるハンズオンを提供できたのではないかと感じています。Yuku Kotani さんのセッションでも語られたように、AI に「このミスを防ぐ静的解析ルールを書いて」と頼むこともできるこの時代、カスタムルールを作るハードルはかつてなく低くなっています。このハンズオンイベントが、この低くなったハードルを跨ぐきっかけとなれば幸いです。

登壇「Language Server と喋ろう」 by pizzacat83

「Language Server と喋ろう」という題でセッションに登壇しました、同じく pizzacat83 です。

このセッションでは、日々の開発を支えるエディタの言語サポート (go to definition, rename など) のコアである Language Server について解説しました。この言語サポートをエディタ操作ではなく programmatic に呼び出すことで実現した自作ツール「危険なコードに到達しうる関数全列挙くん」の紹介もしています。

Language Server に着目したきっかけは、「プロのセキュリティエンジニアによるホワイトボックス診断」をソフトウェアエンジニアリングで最適化する試みです。私は Flatt のソフトウェアエンジニアとして、セキュリティ診断に関わる様々なステークホルダーの業務をソフトウェアで最適化することにより、「非専門家でも簡単に自動診断を実施できる」「セキュリティエンジニアは『人にしかできない』高度な調査だけに集中できる」ことを目指しています。その結晶の一つが、3月にリリースしたセキュリティ診断 AI エージェント「Takumi」です。

セキュリティ診断にまつわる業務をソフトウェアで最適化する際にヒントとなるのが、それらを担う人々の仕事風景を観察することです。Flatt のセキュリティエンジニアたちは月に何度も社内勉強会を開催し、知見やテクニックを共有しています。コードリーディングに特化したエディタのキーバインディングと独自のキー配列、そしてそこから生まれる敏速なエディタさばき。プロのセキュリティエンジニアたちが手足のように活用する言語サポート機能を、ソフトウェアから呼び出すことで何かできないだろうか、と考えたのでした。

同じようなきっかけで、Chrome DevTools の実装を調査したこともあります。こちらについては、また別のイベント「第1回 セキュリティ若手の会(LT&交流会)」で発表しています。

エディタの言語サポート機能をプログラムから呼び出すことで実現したのが、「危険なコードに到達しうる関数全列挙くん」です。セキュリティエンジニアは危なそうな処理を見つけると、呼び出し元を辿り、そのコードがアプリケーションのどの箇所に影響を及ぼすかを調査します。このツールはこの初動を一部自動化するものです。

ホワイトボックス診断を支援するコード解析ツールを開発する際に重視している点は、大きな労力をかけずに様々な言語に適用できることです。Flatt はセキュリティベンダーとして、言語やフレームワークを問わず幅広いアプリケーションのセキュリティを支援するサービスを提供しています。従って、個々の言語に特化したツールを言語の数だけ実装するのでは、開発コストに見合う効果を得るのが難しいという課題があります。この点は、full-stack TypeScript で統一している開発組織が、TypeScript Compiler API を使って静的解析・自動リファクタリングを実現するケースとは対照的です。このような背景から、私は言語にあまり依存しないコード解析技術に関心を持っています2 (サイドイベント「はじめての静的解析」で題材とした ast-grep もその一つです)。

今回の登壇で何より印象的だったことは、プロポーザル投稿から登壇当日までの時代の変化の速さです。自律的なコーディング AI Agent が世の中を席巻したほか、「TypeScript コンパイラを Go で再実装する」という衝撃的なニュース、そしてそのプレビュー版がまさかの TSKaigi Day 1 の朝に発表されました。ちなみに GitHub Copilot Chat の拡張機能が OSS になるというニュースも TSKaigi の前週に飛んできたので、公開されたら実装を読んで発表に含めたいと思っていたのですが、まだ公開には至っていないようですね。この領域のダイナミズムを改めて実感した刺激的な数ヶ月でした。

さてありがたいことに、TSKaigi への登壇は TSKaigi 2024 に続き2年連続となります。去年は「Deno で作る快適な “as Code” プラットフォーム」という題で、私が開発に携わっているセキュリティ SaaS「Shisho Cloud byGMO」のクラウド診断における、カスタム診断ルールを “as TS Code” で書けるようにした仕組みについて紹介しました。去年の登壇を覚えてくださった方もいらっしゃり嬉しい限りです。

TSKaigi 2024・2025 のスピーカー T シャツ

TypeScript の型検査や静的解析は、学生時代の私に「バグを仕組みで防ぐ技術」のありがたみを深く実感させ魅了したきっかけでした。この魅力は、今私が開発者向けのセキュリティプロダクトづくりに打ち込んでいることの原動力にもなっています。これからもこのコミュニティで様々な交流・発信をしていきたいと思っています!

セッション聴講 by xryuseix & しーぴー

今回、TSKaigi に弊社からは多くのエンジニアが参加させていただきましたが、うち 2 名 (xryuseix, しーぴー)はイベント 2 日間、最初から最後までずっっっとセッションの部屋に篭っていました。業務としてカンファレンスに参加し、得られた知見を社内勉強会で還元し、本記事のような場所でも紹介させていただく形です。

そんな 2 人のエンジニアが選ぶ、特に面白くてもっと語りたいと思ったセッションについて、紹介させていただきます!

解説セッション 1: AI Coding Agent Enablement in TypeScript

speakerdeck.com

speaker: Yuku Kotani さん

xryuseix (@ryusei_ishika)です。このセッションではAI エージェントを自走させるために、TypeScript やその周辺エコシステムをどのように整備・活用すべきかが説明されています。

このセッションは主に 3 つの内容で構成されています。

  1. AI エージェントを自走させるための基本的な考え方
  2. イネーブリングの具体的なアプローチ
  3. TypeScript エコシステムの未来

1. AI エージェントを自走させるための基本的な考え方

Yuku Kotani さんは、「自走とは、Human-in-the-Loop を減らすこと」と定義しています。ここでは、「AI が人間の介入なく自律的にできるだけ多くの作業を行える状態」を目指すために、人間が何をすべきかについて考えます。

AI が生成するコードは「任意の TypeScript」など、極めて広い解空間が存在します。そのため、この解空間を可能な限り絞る(=AI に生成させるコードを部分的に強制させる)ことを目標とします。この方法は 2 種類ありますが、このセッションでは「機械的検査」という手法を用います。機械的検査は、古典的な静的解析や自動テストなどを用いて、AI エージェントにフィードバックを与えるような手法です。

つまり、AI に対してコードを生成させるたびに機械的検査を行わせることで、「AI は検査が通るコードが書けるまで無限に修正し続ける」というアプローチをとっています。

2. イネーブリングの具体的なアプローチ

ではどうやって AI にフィードバックを与えれば AI は効率的により”良い”コードを実装するのでしょうか?

ここではいくつかの手段がとられています。

  • 型チェック: TypeScript の型チェック機能を使用
  • 制約付きデコーディング: TS の文法に従わないようなトークン(例えば、{"value"の後ろにはスペースや:などがくるべきで、{がきたらおかしい)をデコーディングの段階で除外
  • 静的解析による Lint: typescript-eslintなどを使用
  • 自動テスト: Jest や Vitest などを使用

でもこれらの手法って実行するまでの準備が面倒じゃないの?と思う方も多いですが、このセッションでは LLM を用いて、イネーブリングアプローチを実践するコードを生成する手法も提案されています。

3. TypeScript エコシステムの未来

2025/5/23、Microsoft は TypeScript の Go 言語実装によるコンパイラのプレビュー版「TypeScript Native Previews」を公開しました。

devblogs.microsoft.com

これにより、TypeScript のコンパイルが 10 倍になるとされています。TypeScript の Go 言語移植の話は「TypeScript ネイティブ移植観察レポート TSKaigi 2025」でも詳しく紹介されています。

この節ではコンパイル 10 倍の爆速 TypeScript が AI エージェントにどのような影響をもたらすかについて記載されていました。前述の通り、AI がコードを生成させるたびに機械的検査を実施します。この機械的検査で Lint を行う場合、Lint が早く実行されないと AI に待たせる時間が発生してしまいます3。つまり、多くのツールチェーンの実行が早くなった結果、AI エージェントによるトライアンドエラーのループが早くなり、より高速に・高性能なソフトウェアを作成できるようになりそうです。

AI Coding Agent Enablement in TypeScript のまとめと感想

このセッションでは、AI エージェントを長い時間自走させるために、TypeScript エコシステムにおけるさまざまなテクニックをご紹介いただきました。LLM による解空間をできるだけ小さくするために、こういった古典的な静的解析などの手法は今後も非常に重要となってくると感じました。

この話についてもっと詳しく知りたい方はYuku Kotani さんの資料をご覧ください!

解説セッション 2: fast-check と neverthrow の PBT+Result 型で堅牢なビジネスロジックを実現する

speakerdeck.com

speaker: Keisuke Uedaさん

しーぴー (@cp20)です。このセッションでは、タイトル通りライブラリを活用した堅牢なビジネスロジック構築手法について説明しています。Web 開発の文脈において、昨今ではフロントエンドだけでなくバックエンドも TypeScript で記述する、いわゆる Full-Stack TypeScript のスタックが珍しくなくなってきました。バックエンドではビジネスロジックを記述することが求められますが、TypeScript でナイーブに記述すると様々な問題を引き起こしかねません。それに対する 2 つのアプローチをこのセッションでは説明しています。

1. ビジネスロジック違反を Result 型で表現する

ビジネスロジックの役割の一つに、ビジネスロジック違反をどのように呼び出し元に伝えるかというものがあります。このような場合 TypeScript では 例外 (Exception) という手法を取ることができます。例外を送出すると、それがキャッチされるまで実行をスキップします。しかし、例外によるビジネスロジック違反の表現にはいくつか問題点があります。

  1. 例外処理を強制できない
  2. 複数の例外を蓄積させるのが難しい

特に「1. 例外処理を強制できない」という問題は、Web サーバーなどに用いる場合ユーザーにエラーメッセージやスタックトレースが漏洩することに繋がり、攻撃のための情報収集に使われる可能性があります。

これに対する 1 つの対策として、ビジネスロジック違反を返り値として表現することを提案しています。

type Ok<T> = { kind: "ok"; value: T };
type Err<E> = { kind: "err"; error: E };
type Result<T, E> = Ok<T> | Err<E>;

このような Result<T, E> 型をビジネスロジックの関数から返すことで、値を使うために例外処理を強制することができます。このような型を自作して使うこともできますが、NeverThrowfp-ts のようなライブラリを使うことで便利なユーティリテイ関数を使うことができます。

2. ビジネスロジックの正当性を PBT で保証する

また、ドメインロジックの正当性を検証するためにテストを書くのは一般的な手法だと思います。しかしユーザー入力を (間接的にでも) 受け付けるときなど、入力の網羅性が必要な際に逐一テストケースを記述していると大変な上に、コーナーケースのチェック漏れなどが発生する可能性があります。

これに対して PBT (Property Based Testing) という手法を提案しています。これは TypeScript においては fast-check のようなライブラリで実現できます。PBT とは入力ケースそのものではなく、入力ケースの持つ性質 (例えば任意のメールアドレス、など) を定義してテストする手法のことで、特にユーザー入力などの予想できない入力に対してテストする時に有効です。

ドメインロジックの誤りは致命的なビジネス上のミスに繋がりかねないので、このようなアプローチを用いて網羅的にテストすることはミスを防止する 1 つの策として有効でしょう。

セッションのまとめと感想

ここまで Result 型と PBT という 2 つの手法をみてきました。これらそれぞれ概念としての手法であり、その具体的なアプローチとしての NeverThrow や fast-check といったライブラリが存在しています。つまり、ライブラリを使わなくてもこれらの手法を取り入れることは可能です。

ビジネスロジックは長期に渡ってメンテナンスすることが予想されるため、なるべく依存を減らして設計するのがベターだと思っています。特に Result 型については Rust などのように言語機能に組み込まれているわけではなく、かつ言語機能での表現があまり難しくない (=自作が簡単) ので、あまりライブラリを使っているケースは多くないように思います。NeverThrow は Result 型とそれに付随するユーティリテイ関数が大きな魅力だと思うので、そことのトレードオフで導入を考えてみるのが良いのではないでしょうか。

一方 PBT は自作がある程度面倒くさい領域だと思っています。テストコード自体は本体のソースコードとは分離されている (=影響範囲が高々テストのみ) はずなので、予測できない入力を扱うドメインロジックを記述する際には導入を検討してみても良いのではないかと思います。

もしこの話題について気になった方は、実際のソースコードなどを用いて説明している資料を見てみることをおススメします!

出展ブースにおける「型 & セキュリティ」クイズ by se0r12

TSKaigi 2025にて、弊社ブースで出していたクイズの作問を担当したse0r12です。

クイズに挑んでいただき誠にありがとうございました。 ここでは、簡単にクイズについてのお話と、作問して見た感想を書かせていただければと思います。

Takumiが鎮座するブースで「型 & セキュリティ」クイズを出題しました

問題と解答

正解を見るにはこちらをクリック 正解: 1

const safeUser = await prisma.user.findUnique({
  where: { email }
}) as Omit<User, "hashedPassword">;

正解の選択肢における as Omit<User, "hashedPassword"> の部分はTypeScriptの「型アサーション」と呼ばれる機能を利用しています。これはプログラマーがTypeScriptコンパイラに対して、「この safeUser というデータは、User 型から hashedPassword を取り除いた形として扱ってくださいね」と伝えるだけのものです。
ランタイム時にはこの型アサーションの情報は消えてしまい、safeUser の中身には依然として hashedPassword が含まれたままになり、そのままレスポンスに含まれてしまいます。

解説

まず今回のクイズについてですが、TypeScriptにおける「ビルド前とランタイム時の差」を問う内容でした。

TypeScriptには型情報があるので開発の段階 (ビルド前)では、ある変数に対して代入される値に対して、型による制限が可能です。 しかしながら、ランタイム時には型情報は抜け落ちるため制限がなくなります。 このことから例えば、開発時はある変数をstring型としていても、ランタイム時のチェックをしない場合、想定していない型の値が代入され、それをアプリケーションが扱う可能性があります。 これをクイズに落とし込むために、今回はas Omit<Type, Keys> を利用しました。

次に作問してみた感想です。 今回のクイズは「1分程度考えて、パソコンをカタカタしなくても解ける難易度」になるように心がけました。 私は今回はブースに立たなかったので挑戦してくださった方の反応を見れていませんが、数秒で解かれたという話も聞きつつも、悪くない難易度のクイズだったのかなと感じています。 クイズ挑戦者の正答率が6-7割程度という話を聞いたので、想定よりは少し難しかった可能性がありますが、8割程度の人が解けると嬉しいなと思って出していたので概ね予想通りであるからです。

このことから、難易度調整はそれなりに良さそうだったかなと思いつつも、クイズに対しての個人的な反省点は勿論あります。 例えば、Prismaのquery option (omit, select)に頼りすぎたことが挙げられ、selectではなくlodash.omitの選択肢があっても良かったなと感じています。 このように反省点はすぐに思いつくものの、良かった点があまり思いつかない事に多少辛くなりつつ...

ポジティブな感想を絞り出すとしたら、「クイズに挑戦をしてみようかな」と思ってもらえるクイズを作れた(気がする)ことでしょうか。 また、今の所「GMO Flatt Securityの作るTSKaigiのクイズはつまらなかったです」という意見は見てないので少し安心しています。

さて、最後となりますが、クイズに挑んでくださった方誠にありがとうございました。 私の作成したクイズがセッション合間の小休止の役割を担えていればとても嬉しく思います。

TSKaigi 2025 運営スタッフ by OJI

イネーブルメントプラットフォーム部で Shisho Cloud byGMO の開発をしています OJI です。

TSKaigi 2024 に引き続き 2025 でも運営委員として TSKaigi の運営に携わりました。

今年は「参加者体験企画チーム」のリーダーとして、多くのメンバーと協力しながら様々な企画を設計・実施を主導しました。このチームは名前の通り TSKaigi に参加するすべての方々が TSKaigi を通じて得られる体験に焦点を当てて、どうすれば参加者がより楽しく、より心地よく TSKaigi という空間を過ごせるかを考え続けるチームです。 具体的には名札に貼れるカスタムシールであったり、懇親会前に開催された OST、プチミートアップなどは参加者体験企画チームによる主導で進めてきました。

カスタムシールが貼られたpizzacat83の名札

時間的制約や人的リソースの面で諦めた企画も多々ありましたが、最後の最後まで「どうすれば参加者が楽しめる企画になるか?」をチーム全員で考えられたのは他では得ることができない貴重な時間です(企画によっては開始直前まで導線や流れを当日の様子に合わせて調整する、みたいなこともしていました)。 今年評判の良かった企画はより洗練した形で、実現できなかった企画や今年思いつかなかった企画はまずは実現して参加者の皆さんがさらに TSKaigi を楽しんでいただけるよう来年も運営として頑張ります。

終わりに

GMO Flatt Securityは引き続き "エンジニアの背中を預かる" ため、技術コミュニティへの貢献を続けてまいります。最新情報は公式Xでご確認ください。

また、サービス提供を通じて開発組織のセキュリティを支援してまいります。プロフェッショナルによる脆弱性診断・ペネトレーションテストは無料でお見積もりが可能です。お気軽にお問い合わせください。

AIエージェント「Takumi」はWebから今すぐ利用できます。

それでは、ここまでお読みいただきありがとうございました!


  1. より詳細な調査リポートは「GMO Flatt Security Top 10 - 2025年版」よりご覧いただけます。
  2. こうは書いたものの、JavaScript・TypeScript に限っては、言語に特化したコード解析技術も積極的に探求していきたいと思っています。なぜならば、現代の Web アプリケーションのほとんどは、少なくともフロントエンドを JS・TS で実装しており、言語に特化したツールであっても多くのアプリケーションで活用できるからです。
  3. Lint の実行には TypeScript のコンパイルは関係ないのでは?と一瞬思うかもしれませんが、typescript-eslint などの Linter は Lint の過程で Type Check が走ります。前述の「コンパイル」には Type Check とトランスパイルの二つの処理を含みます。