$30 off During Our Annual Pro Sale. View Details »

昔の) PHP が誇った最高の機能 register_globals の真実、そして未来へ

昔の) PHP が誇った最高の機能 register_globals の真実、そして未来へ

Wataru MIYAGUNI

August 21, 2015
Tweet

More Decks by Wataru MIYAGUNI

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. register globals

    View Slide

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

    View Slide

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

    View Slide


  19. register globals = off

    View Slide


  20. register globals = on

    View Slide


  21. register globals = on

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. とてもお手軽なのです

    View Slide

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

    View Slide

  34. 残念ながら
    間違ってます

    View Slide

  35. 使っては
    いけない

    View Slide

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

    View Slide

  37. その1
    $_FILES

    View Slide

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

    View Slide

  39. $ FILES 例 (1)

    View Slide

  40. $ FILES 例 (1)

    View Slide

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

    View Slide

  42. register globals 効果により

    View Slide

  43. register globals 効果により

    View Slide

  44. register globals 効果により

    View Slide

  45. register globals 効果により

    View Slide

  46. register globals 効果により

    View Slide

  47. register globals 効果により

    View Slide

  48. register globals 効果により

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. その2
    $_SESSION

    View Slide

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

    View Slide

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

    View Slide

  57. $ SESSION + register globals

    View Slide

  58. $ SESSION + register globals

    View Slide

  59. $ SESSION + register globals

    View Slide

  60. $ SESSION + register globals

    View Slide

  61. $ SESSION + register globals

    View Slide

  62. $ SESSION + register globals

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  70. Usage
    (new Gongo\MercifulPolluter\Request)->pollute();
    // main routine
    pollute() を呼び出すとグローバル変数へのアサ
    インが行われる

    View Slide

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

    View Slide

  72. Usage (with magic quotes gpc)
    $request = new Gongo\MercifulPolluter\Request;
    $request->enableMagicQuotesGpc();
    $request->pollute();
    // ...

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide