Slide 1

Slide 1 text

Webアプリケーションの ユーザ入力検証 xryuseix (@ryusei_ishika)

Slide 2

Slide 2 text

講演内で使用するソースコードについて https://github.com/SECCON/2023_beginnerslive これ 1. GitHubリポジトリへアクセスしてください 2. xryuseixフォルダの中のREADMEを読んでください 2

Slide 3

Slide 3 text

自己紹介 ID: xryuseix (Twitter: @ryusei_ishika) Webセキュリティと開発が好きです。 ctf4b 2023では以下の問題を提供しました。 ● shaXXX ● drmsaw ● phisher2 3

Slide 4

Slide 4 text

ユーザの入力をちゃんとチェックしてますか? これってstring? number? https://expressjs.com/ja/starter/hello-world.html 4

Slide 5

Slide 5 text

ユーザの入力をちゃんとチェックしてますか? https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch この中身って保証されてる? 5

Slide 6

Slide 6 text

ユーザの入力をちゃんとチェックしてますか? https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch undefinedにならない?大丈夫? 6

Slide 7

Slide 7 text

Q1. if文書けば解決するのでは? A. プロパティの数が少なければそれで良いが、多い場合は大変 想定していないプロパティが含まれていないかチェックする 必要もある 7

Slide 8

Slide 8 text

Q2. TypeScriptを使えば解決するのでは? A. えっこうですか?? 8

Slide 9

Slide 9 text

Q2. TypeScriptを使えば解決するのでは? A. えっこうですか??(2) プロパティが多かったり入れ子になってたりしたら 実装がかなり増えてキツくないですか? 9

Slide 10

Slide 10 text

Q3. いやでもさ...... 󰬣「これって実行時エラーが出るだけで、 脆弱性にならんのとちゃうんか??」 😎「クックックッ......」 ※僕は大阪弁喋れません 10

Slide 11

Slide 11 text

今回使用するサンプル問題 corCTF-2021 web/buymeより一部改変 ここをユーザが自由に書き換えられる https://github.com/SECCON/2023_beginnerslive/blob/main/xryuseix/chall.js 問題サーバ: https://x-beginnerslive2023.deno.dev 11

Slide 12

Slide 12 text

今回使用するサンプル問題 corCTF-2021 web/buymeより一部改変 ● フラグはflagsオブジェクトにある ● buyFlag関数でフラグが買える場合は 買ってretuenしている ● 買えるフラグはuserとadminで異なる。 userの場合はフラグが偽物で、admin の場合はフラグが高額 12

Slide 13

Slide 13 text

今回使用するサンプル問題 corCTF-2021 web/buymeより一部改変 ● サーバはDeno.serveで実装されてお り、ユーザの入力はクエリパラメータで 受け取れる (今回Denoを使っていることに深い意 味はありません) ● ユーザの入力はmain関数に送られ、 JSONをパースした後にroleが指定さ れているか確認する ● その後、buyFlag関数にユーザ情報と ロール情報が送られる 13

Slide 14

Slide 14 text

今回使用するサンプル問題 ⚠次のスライドで答えを言及します 見たくない場合は1分くらい下の猿のモノマネしててください。 答えはレポジトリ内にも書かれています。 14

Slide 15

Slide 15 text

今回使用するサンプル問題(解説) こんな感じのJSONを送れば良いです。 buyFlag関数の呼び出しの箇所で、スプレッド構文を使っているため、 userオブジェクトの中身を書き 換えられます。 15

Slide 16

Slide 16 text

prototype pollution 脆弱性を埋め込むパターンは他にも... https://www.youtube.com/watch?v=LUsiFV3dsK8&t=67s のコードを一部改変 16

Slide 17

Slide 17 text

Zodという選択肢もある https://zod.dev/?id=basic-usage Zodは静的型推論による TypeScript ファーストのスキーマ検証ツールです。 文字列、数字、オブジェクトなどが特定のスキーマ (≒型※1 )に一致しているか確認することができます。 → ユーザの入力を検証することができる! 文字列のスキーマ “tuna”は文字列なのでOK 12は文字列ではないのでエラー ※1 正確には違うが、そう考えた方がわかりやすいかもしれない 17

Slide 18

Slide 18 text

Zodという選択肢もある https://zod.dev/ 18

Slide 19

Slide 19 text

まずはTypeScriptで書き換えてみる https://github.com/SECCON/2023_beginnerslive/blob/main/ xryuseix/chall.ts 19

Slide 20

Slide 20 text

まずはTypeScriptで書き換えてみる https://github.com/SECCON/2023_beginnerslive/blob/main/ xryuseix/chall.ts 前述の通り、単純にTypeScriptにした からといって修正できるとは限りません 20

Slide 21

Slide 21 text

Zodを使って書き換えてみる https://github.com/SECCON/2023_beginnerslive/blob/main/xryuseix/fixed.ts Zodスキーマを定義 検証 21

Slide 22

Slide 22 text

EmailやUrl、IPなど、 いろんな文字列に対して検証できる Zodなら様々な検証ができる 22

Slide 23

Slide 23 text

● ユーザの入力を検証する事は 安全なアプリケーション開発において重要 ● TypeScriptを使ったからといって ユーザの入力内容は保証できない ● 入力を検証する方法の1つの手段として、 Zodというものがある まとめ 思わぬ入力が与えられて ゾッと しないように、気をつけてコードを書こう! 23