Slide 1

Slide 1 text

(昔の) PHP が誇った 最高の機能 register globals その真実 そして未来へ @gongoZ (Wataru MIYAGUNI) YAPC::Asia Tokyo 2015

Slide 2

Slide 2 text

自己紹介 ˆ 宮國 渡 ˆ ごんご ˆ おきなわ ˆ @gongoZ ˆ github.com/gongo ˆ Emacs で PHPer

Slide 3

Slide 3 text

自己紹介(Con’t) ˆ 肉体言語 Tython 開発者 ˆ 世界で唯一 Hello, World を実行できた人間

Slide 4

Slide 4 text

自己紹介(Con’t) ˆ Emacs で書いてる文章の中で「一句」を教えてくれる Emacs Lisp ˆ http: //qiita.com/gongo/items/a0809d6e3bb6a4d925eb

Slide 5

Slide 5 text

実用性のないものを 作るのが趣味

Slide 6

Slide 6 text

そんなわけで PHP の話します

Slide 7

Slide 7 text

みなさん PHP 使っていますか

Slide 8

Slide 8 text

みなさん PHP ≥ 5.4 使っていますか

Slide 9

Slide 9 text

お知らせです PHP 5.4 の セキュリティサポートは 2015年9月14日 までです 忘れずに PHP 5.5 以上にアップデートしましょう See: PHP: Supported Versions

Slide 10

Slide 10 text

あらためて、みなさん PHP 使っていますか

Slide 11

Slide 11 text

あらためて、みなさん PHP < 5.4 使ってるんですか

Slide 12

Slide 12 text

あらためて、みなさん どうして 5.4 に行かないんですか

Slide 13

Slide 13 text

_人人人人人人_ > 5.3 の壁 <  ̄YYYYYY ̄

Slide 14

Slide 14 text

See: PHP: 下位互換性のない変更点 - Manual

Slide 15

Slide 15 text

See: PHP: 下位互換性のない変更点 - Manual

Slide 16

Slide 16 text

register globals

Slide 17

Slide 17 text

register globals とは register globals を on とした場合、この機能 により、HTML フォームから投稿される 変数と同時に、あらゆる種類の変数がス クリプトに注入されることになります。 これは、PHP においては変数の初期化が 不要であるということにも関係し、 安全 でないコードを書くことが極めて容易に なるということを意味します。 See: PHP: グローバル変数の登録機能の使用法 - Manual

Slide 18

Slide 18 text

register globals とは register globals を on とした場合、この機能 により、HTML フォームから投稿される 変数と同時に、あらゆる種類の変数がス クリプトに注入されることになります。 これは、PHP においては変数の初期化が 不要であるということにも関係し、 安全 でないコードを書くことが極めて容易に なるということを意味します。 See: PHP: グローバル変数の登録機能の使用法 - Manual

Slide 19

Slide 19 text

例 register globals = off

Slide 20

Slide 20 text

例 register globals = on

Slide 21

Slide 21 text

例 register globals = on

Slide 22

Slide 22 text

未だ on のアプリの特徴 日頃からグローバル変数を嗜んで いる クラスが存在しなかった時代からの遺産とか

Slide 23

Slide 23 text

off にできない理由の一つ 全てのグローバル変数をチェック して自分で定義したやつはそのま まにしておいてリクエストデータ であれば $_GET などのリクエスト データを扱うスーパーグローバル 変数に置き換える作業をしないと ああああああああめんどくさいあ ああああああああああ

Slide 24

Slide 24 text

めんどくさい例 目の前にあるグローバル変数が リクエストデータ なのか スクリプトで定義した変数 なのかがわからない

Slide 25

Slide 25 text

めんどくさい例 目の前にあるグローバル変数が リクエストデータ なのか スクリプトで定義した変数 なのかがわからない

Slide 26

Slide 26 text

人は怠惰である どうにか最小限の変更で (古いコードのまま) PHP 5.4 に上げたい register_globals を再現す るいい方法ないの???

Slide 27

Slide 27 text

人は怠惰である どうにか最小限の変更で (古いコードのまま) PHP 5.4 に上げたい register_globals を再現す るいい方法ないの??? あるぞ!! 超簡単だぜ!!

Slide 28

Slide 28 text

php.net が教える秘策 This will emulate register globals On. See: PHP: Miscellaneous Questions - Manual

Slide 29

Slide 29 text

秘策解説 (1) register globals が影響するスーパーグローバル変数 (連 想配列) を順番に見て

Slide 30

Slide 30 text

秘策解説 (2) extract() を使って現在のスコープ (この場合はグローバ ル) に、キーと同じ名前の変数をアサインする

Slide 31

Slide 31 text

さきほどのコードを entrypoint に書いておけば register globals っぽい動きが 再現できます

Slide 32

Slide 32 text

とてもお手軽なのです

Slide 33

Slide 33 text

とてもお手軽なこの方法は

Slide 34

Slide 34 text

残念ながら 間違ってます

Slide 35

Slide 35 text

使っては いけない

Slide 36

Slide 36 text

register globals には php.net に載っていない 隠された仕様がある ˆ 隠しているわけではないと思うが書かれてない ˆ 自分が見つけれていないだけだと信じてる

Slide 37

Slide 37 text

その1 $_FILES

Slide 38

Slide 38 text

$ FILES とは HTTP POST メソッドで現在のス クリプトにアップロードされた項 目の連想配列です。 See: PHP: $ FILES - Manual

Slide 39

Slide 39 text

$ FILES 例 (1)

Slide 40

Slide 40 text

$ FILES 例 (1)

Slide 41

Slide 41 text

$ FILES 例 (2) POST すると $ FILES はこうなります

Slide 42

Slide 42 text

register globals 効果により

Slide 43

Slide 43 text

register globals 効果により

Slide 44

Slide 44 text

register globals 効果により

Slide 45

Slide 45 text

register globals 効果により

Slide 46

Slide 46 text

register globals 効果により

Slide 47

Slide 47 text

register globals 効果により

Slide 48

Slide 48 text

register globals 効果により

Slide 49

Slide 49 text

_人人人人人人人人人人_ > $upload_tmp_name < > にしとけよ!!  <  ̄YYYYYYYYYY ̄

Slide 50

Slide 50 text

おまけ register globals が on の状態で $ FILES に対して extract() を実行して EXTR SKIP を指定すると、 その結果に驚くことでしょう 。 See: PHP: extract - Manual  

Slide 51

Slide 51 text

おまけ register globals が on の状態で $ FILES に対して extract() を実行して EXTR SKIP を指定すると、 その結果に驚くことでしょう 。 See: PHP: extract - Manual  

Slide 52

Slide 52 text

おまけ register globals が on の状態で $ FILES に対して extract() を実行して EXTR SKIP を指定すると、 その結果に驚くことでしょう 。 See: PHP: extract - Manual ちゃんと書け

Slide 53

Slide 53 text

$ FILES まとめ ˆ そのまま extract() 使うと死ぬ ˆ tmp_name だけ規則違うから注意な See: http://gongo.hatenablog.com/entry/2014/10/02/211520

Slide 54

Slide 54 text

その2 $_SESSION

Slide 55

Slide 55 text

$ SESSION とは 現在のスクリプトで使用できる セッション変数を含む連想配列 です。 See: PHP: $ SESSION - Manual

Slide 56

Slide 56 text

$ SESSION も対象です EGPCS(Environment, GET, POST, Cookie, Server) 変数を グローバル変数として登録するかどうかを 指定します。 See: PHP: register globals - Manual Session とは一言も書いてない けど Session も対象です

Slide 57

Slide 57 text

$ SESSION + register globals

Slide 58

Slide 58 text

$ SESSION + register globals

Slide 59

Slide 59 text

$ SESSION + register globals

Slide 60

Slide 60 text

$ SESSION + register globals

Slide 61

Slide 61 text

$ SESSION + register globals

Slide 62

Slide 62 text

$ SESSION + register globals

Slide 63

Slide 63 text

$ SESSIONS まとめ ˆ リファレンス渡しされるので注意な ˆ session_start() のタイミングでグ ローバル変数にアサインされるので、 同キー名があれば (たぶん) EGPCS よ りも強い(上書きする) ˆ 余談ですが EGPCS の順番は variables order の設定で 決まる See: http://gongo.hatenablog.com/entry/2014/12/24/132841

Slide 64

Slide 64 text

そんなわけで ˆ register globals の仕様を深く知ること ができました ˆ もし PHP 5.3 → 5.4 を挑戦している方 は、グローバル変数と引き続きがん ばってください

Slide 65

Slide 65 text

「それでもめんどくさい」

Slide 66

Slide 66 text

「仕組みはわかったからどうすれ ば 5.4 に上げられるの?」

Slide 67

Slide 67 text

そんな貴方に便利な!! ˆ github.com/gongo/merciful-polluter ˆ packagist.org/packages/gongo/merciful-polluter merciful polluter  

Slide 68

Slide 68 text

そんな貴方に便利な!! ˆ github.com/gongo/merciful-polluter ˆ packagist.org/packages/gongo/merciful-polluter merciful polluter 慈悲深い汚染 (直訳)

Slide 69

Slide 69 text

Installation $ composer require gongo/merciful-polluter packagist に登録済みなので composer で Get で きる

Slide 70

Slide 70 text

Usage pollute(); // main routine pollute() を呼び出すとグローバル変数へのアサ インが行われる

Slide 71

Slide 71 text

Usage (with $ SESSION) pollute(); // ... session_start(); (new Gongo\MercifulPolluter\Session)->pollute(); // ...

Slide 72

Slide 72 text

Usage (with magic quotes gpc) enableMagicQuotesGpc(); $request->pollute(); // ...

Slide 73

Slide 73 text

Supported Version See: merciful-polluter/.travis.yml at master gongo/merciful-polluter

Slide 74

Slide 74 text

Supported Version いつまでも使える!!

Slide 75

Slide 75 text

まとめのまとめ ˆ はやく PHP 5.4 以上にしよう ˆ 脆弱性残ったままなので危険です ˆ merciful polluter 使わない未来にしていこう ˆ スーパーグローバル変数汚染は防いでいるものの、そ れ以外は通常の仕様のままなのでやはり危険です ˆ PHP 7 に register globals を持っていかないよ うに ˆ 7 に相応しくない  

Slide 76

Slide 76 text

まとめのまとめ ˆ はやく PHP 5.4 以上にしよう ˆ 脆弱性残ったままなので危険です ˆ merciful polluter 使わない未来にしていこう ˆ スーパーグローバル変数汚染は防いでいるものの、そ れ以外は通常の仕様のままなのでやはり危険です ˆ PHP 7 に register globals を持っていかないよ うに ˆ 7 に相応しくない no register globals, now PHP