Slide 1

Slide 1 text

「攻め」と「守り」で理解する PHP アプリケーション 2025/06/28 - PHP Conference Japan 2025 GMO Flatt Security株式会社 てぃー / k1rnt

Slide 2

Slide 2 text

自己紹介 てぃー @k1rnt & GMO Flatt Security(株) セキュリティエンジニ) & 週末はCTFしたり旅をした & 最近は逆流性食道炎がつらいです

Slide 3

Slide 3 text

AIからのPR おっと急にAIからPRが → 見てみましょう

Slide 4

Slide 4 text

AIからのPR どうやら、bタグとiタグだけ許可したいPRのようですね さて、このままマージして良いでしょうか?

Slide 5

Slide 5 text

AIからのPR

Slide 6

Slide 6 text

AIからのPR このコードには脆弱性が存在します。 一見エスケープしているので安全のように見えますが、 preg_replaceを使用してb, iタグを復元します

Slide 7

Slide 7 text

AIからのPR click

Slide 8

Slide 8 text

AIからのPR

Slide 9

Slide 9 text

AIからのPR これまで、多くの脆弱性はフレームワークにより防がれてきた しかし、現代ではAIが大量に吐くコードに混入する 脆弱性をレビュー時に見過ごす危険性が生まれている 「脆弱性を生まない書き方」だけではなく 検出するということの重要性が増してきた

Slide 10

Slide 10 text

AIからのPR 実際なんも考えなかったらXSS出してきますし、、、 出典: 弊社ブログ( ) https://blog.flatt.tech/entry/ai_code_security

Slide 11

Slide 11 text

AIからのPR また、XSSってそんな中で残り続けた脆弱性でもあるんですよね 出典: 弊社ブログ( ) https://blog.flatt.tech/entry/flatt_top10_2025

Slide 12

Slide 12 text

AIからのPR 今回話すような内容をおさらいしつつ、 自分で書かないのはもちろん、 AIに書かせない/書いたら検出するのが重要ですよね。

Slide 13

Slide 13 text

このセッションで持ち帰れるもの 攻撃者目線で診る PHPアプリケーションでの XSS発生パターンと対策ポイント

Slide 14

Slide 14 text

アジェンダ P blade Template EngineにおけるXS9 P Unicode NormalizationによるXS9 P PHPのパラメータ上限によるCSP Bypas P おわりに

Slide 15

Slide 15 text

blade Template EngineにおけるXSS bladeの と の違いの説明 {{ $var }} {!! $var !!}

Slide 16

Slide 16 text

blade Template EngineにおけるXSS {{ $var }}

Slide 17

Slide 17 text

blade Template EngineにおけるXSS https://readouble.com/laravel/12.x/ja/blade.html

Slide 18

Slide 18 text

blade Template EngineにおけるXSS 実装してみましょう

Slide 19

Slide 19 text

blade Template EngineにおけるXSS XSSは発生しないですね

Slide 20

Slide 20 text

blade Template EngineにおけるXSS {!! $var !!}

Slide 21

Slide 21 text

blade Template EngineにおけるXSS https://readouble.com/laravel/12.x/ja/blade.html

Slide 22

Slide 22 text

blade Template EngineにおけるXSS 実装してみましょう

Slide 23

Slide 23 text

blade Template EngineにおけるXSS ドキュメントにもある通りXSSが発生しました

Slide 24

Slide 24 text

blade Template EngineにおけるXSS 対策方法 y {{ $var }} を使用すV y どうしても {!! $var !!} が必要な場合は、mewebstudio/ Purifier 
 などを使用して、適切にサニタイズを行8 p https://github.com/mewebstudio/Purifier

Slide 25

Slide 25 text

blade Template EngineにおけるXSS ここまでは皆さんご存知だと思います でも、、、

Slide 26

Slide 26 text

blade Template EngineにおけるXSS Laravelの {!! $var !!} の実装まで 読んだことはありますか?

Slide 27

Slide 27 text

blade Template EngineにおけるXSS {!! $var !!}

Slide 28

Slide 28 text

blade Template EngineにおけるXSS {!! で雑にgrepをかけると次のコードが見える

Slide 29

Slide 29 text

blade Template EngineにおけるXSS 使用箇所は?

Slide 30

Slide 30 text

blade Template EngineにおけるXSS {{ $var }}

Slide 31

Slide 31 text

blade Template EngineにおけるXSS $wrappedでは、sprintf() でechoFormatを使っている

Slide 32

Slide 32 text

blade Template EngineにおけるXSS $echoFormatはe(%s)、つまりエスケープしている!

Slide 33

Slide 33 text

blade Template EngineにおけるXSS つまり安全!

Slide 34

Slide 34 text

blade Template EngineにおけるXSS 本当に? e() の実装まで知ってる?

Slide 35

Slide 35 text

blade Template EngineにおけるXSS ... 追います

Slide 36

Slide 36 text

blade Template EngineにおけるXSS e()

Slide 37

Slide 37 text

blade Template EngineにおけるXSS 実装を見つける

Slide 38

Slide 38 text

blade Template EngineにおけるXSS よく見ると、安全ではないケースがあります

Slide 39

Slide 39 text

blade Template EngineにおけるXSS instanceがHtmlableである時 エスケープ処理せずに返しています

Slide 40

Slide 40 text

blade Template EngineにおけるXSS 事前にこのようにmarkdownをプレビューしたいみたいな場合は?

Slide 41

Slide 41 text

blade Template EngineにおけるXSS まぁ {{ $content }} なのでXSSは発生しないよね...?

Slide 42

Slide 42 text

blade Template EngineにおけるXSS XSS発生する

Slide 43

Slide 43 text

blade Template EngineにおけるXSS つまり、{{ $var }} でエスケープを行い 、 かつ $var には Htmlable なインスタンスでないか確認すれば安全。

Slide 44

Slide 44 text

blade Template EngineにおけるXSS 今回のようなケースでは、入力値のタグをエスケープしつつ、 javascript:, data:, といった危険なスキームを拒否することで 安全になる

Slide 45

Slide 45 text

blade Template EngineにおけるXSS

Slide 46

Slide 46 text

Unicode NormalizationによるXSS じゃあエスケープしていれば安全なんだね?

Slide 47

Slide 47 text

Unicode NormalizationによるXSS 半分正解 エスケープ後の文字列に変なことしていなければね

Slide 48

Slide 48 text

Unicode NormalizationによるXSS 変なことって?

Slide 49

Slide 49 text

Unicode NormalizationによるXSS 例えばこんなコードはどうでしょうか

Slide 50

Slide 50 text

Unicode NormalizationによるXSS WP HTMLエスケーT 7P アプリケーションの標準であるUTF-8に変I #P ASCIIに直す

Slide 51

Slide 51 text

Unicode NormalizationによるXSS どういう時にこんなコードが書かれるの?

Slide 52

Slide 52 text

Unicode NormalizationによるXSS 例えば、caféみたいに入力された文字列をcafeとして システムに登録したい場面があるかもしれない

Slide 53

Slide 53 text

Unicode NormalizationによるXSS もちろんエスケープ済みなので、XSSも発生しない

Slide 54

Slide 54 text

Unicode NormalizationによるXSS 大丈夫そうじゃない?

Slide 55

Slide 55 text

Unicode NormalizationによるXSS ほんと? じゃあ (っ'-')╮«svg/onload%3Dalert(1)»

Slide 56

Slide 56 text

Unicode NormalizationによるXSS どうしてこんなことに...?

Slide 57

Slide 57 text

Unicode NormalizationによるXSS «svg/onload%3Dalert(1)» %C2%ABsvg/onload%3Dalert(1)%C2%BB

Slide 58

Slide 58 text

Unicode NormalizationによるXSS %C2%AB と %C2%BB のそれぞれがASCIIに正規化されると、 << や >> となり、通常のタグと同等のものになる

Slide 59

Slide 59 text

Unicode NormalizationによるXSS よって、 <> となりhtmlとして認識されXSSが発生する

Slide 60

Slide 60 text

Unicode NormalizationによるXSS 出力の直前にエスケープをすることで安全に扱うことができる エスケープ後にその文字列の操作を行わないことが大事

Slide 61

Slide 61 text

PHPのパラメータ上限によるCSP Bypass さて、ここまでの内容、AIが暴走した時に止められると思いますか? 結構しんどくないですか? CSPは有効な手段のひとつです

Slide 62

Slide 62 text

PHPのパラメータ上限によるCSP Bypass https://developer.mozilla.org/ja/docs/Web/HTTP/Guides/CSP CSPとは?

Slide 63

Slide 63 text

PHPのパラメータ上限によるCSP Bypass CSPとは? つまり、「このページでは信頼した場所のリソースだけ読み込め」 とブラウザに命令し、怪しいスクリプトや攻撃コードの実行を 防ぐ仕組みです

Slide 64

Slide 64 text

PHPのパラメータ上限によるCSP Bypass 実装してみましょう

Slide 65

Slide 65 text

PHPのパラメータ上限によるCSP Bypass この状態では、CSPがありエスケープせずともブラウザでエラーが出力 そして、XSSは発生しない

Slide 66

Slide 66 text

PHPのパラメータ上限によるCSP Bypass ただし、、、 PHPではなんとCSPヘッダーの前に応答が送信され、 ヘッダーが無視されます場合があります...

Slide 67

Slide 67 text

PHPのパラメータ上限によるCSP Bypass 今度はPHP本体のソースコードを確認します

Slide 68

Slide 68 text

PHPのパラメータ上限によるCSP Bypass $_GET は max_input_varsより最大値が1000であることが分かります

Slide 69

Slide 69 text

PHPのパラメータ上限によるCSP Bypass ここではソースは示しませんが同様に調査を行うと下記がわかります。 PHPでのデフォルトの最大パラメータg € $_GET: 1000 parametere € $_POST: 1000 parametere € $_FILES: 20 files

Slide 70

Slide 70 text

PHPのパラメータ上限によるCSP Bypass では、この最大数を超えるパラメータを送るとどうなるのか? Devtoolsにこのペイロードを投げる document.location = '/?xss=&'+'a=x&'.repeat(1000)

Slide 71

Slide 71 text

PHPのパラメータ上限によるCSP Bypass

Slide 72

Slide 72 text

PHPのパラメータ上限によるCSP Bypass 対策方法は? 現状のPHPではこれが仕様 なので、CSPに頼り切らずエスケープをちゃんとしましょう

Slide 73

Slide 73 text

おわりに いかがだったでしょうか? XSS対策って意外と見ることが多くて大変でしたね 最後におさらいとして、なにを書かせてはいけないのか見てみましょう

Slide 74

Slide 74 text

おわりに 出力を行う前にエスケープを行う エスケープをどうしてもできない場合は、信頼できるライブラ リで適切にサニタイズを行う 出力の直前にエスケープを行い、エスケープ後にその文字列の 操作を行わない CSPを適切に設定する

Slide 75

Slide 75 text

おわりに アプリケーションやパブリッククラウドのセキュリティは におまかせください プロフェッショナルによる 脆弱性診断・ペネトレーションテスト セキュリティコードレビューに 特化したAIエージェント Takumi セキュリティ診断AIエージェント