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

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

8519a654e3b51ef7dd19486a859ca91c?s=128

Wataru MIYAGUNI

August 21, 2015
Tweet

Transcript

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

    MIYAGUNI) YAPC::Asia Tokyo 2015
  2. 自己紹介 ˆ 宮國 渡 ˆ ごんご ˆ おきなわ ˆ @gongoZ

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

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

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

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

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

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

  9. お知らせです PHP 5.4 の セキュリティサポートは 2015年9月14日 までです 忘れずに PHP 5.5

    以上にアップデートしましょう See: PHP: Supported Versions
  10. あらためて、みなさん PHP 使っていますか

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

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

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

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

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

  16. register globals

  17. register globals とは register globals を on とした場合、この機能 により、HTML フォームから投稿される

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

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

  20. 例 register globals = on

  21. 例 register globals = on

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

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

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

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

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

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

    超簡単だぜ!!
  28. php.net が教える秘策 This will emulate register globals On. See: PHP:

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

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

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

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

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

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

  35. 使っては いけない

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

  37. その1 $_FILES

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

    $ FILES - Manual
  39. $ FILES 例 (1)

  40. $ FILES 例 (1)

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

  42. register globals 効果により

  43. register globals 効果により

  44. register globals 効果により

  45. register globals 効果により

  46. register globals 効果により

  47. register globals 効果により

  48. register globals 効果により

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

  50. おまけ register globals が on の状態で $ FILES に対して extract()

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

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

    を実行して EXTR SKIP を指定すると、 その結果に驚くことでしょう 。 See: PHP: extract - Manual ちゃんと書け
  53. $ FILES まとめ ˆ そのまま extract() 使うと死ぬ ˆ tmp_name だけ規則違うから注意な

    See: http://gongo.hatenablog.com/entry/2014/10/02/211520
  54. その2 $_SESSION

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

    - Manual
  56. $ SESSION も対象です EGPCS(Environment, GET, POST, Cookie, Server) 変数を グローバル変数として登録するかどうかを

    指定します。 See: PHP: register globals - Manual Session とは一言も書いてない けど Session も対象です
  57. $ SESSION + register globals

  58. $ SESSION + register globals

  59. $ SESSION + register globals

  60. $ SESSION + register globals

  61. $ SESSION + register globals

  62. $ SESSION + register globals

  63. $ SESSIONS まとめ ˆ リファレンス渡しされるので注意な ˆ session_start() のタイミングでグ ローバル変数にアサインされるので、 同キー名があれば

    (たぶん) EGPCS よ りも強い(上書きする) ˆ 余談ですが EGPCS の順番は variables order の設定で 決まる See: http://gongo.hatenablog.com/entry/2014/12/24/132841
  64. そんなわけで ˆ register globals の仕様を深く知ること ができました ˆ もし PHP 5.3

    → 5.4 を挑戦している方 は、グローバル変数と引き続きがん ばってください
  65. 「それでもめんどくさい」

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

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

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

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

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

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

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

    $request->enableMagicQuotesGpc(); $request->pollute(); // ...
  73. Supported Version See: merciful-polluter/.travis.yml at master gongo/merciful-polluter

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

  75. まとめのまとめ ˆ はやく PHP 5.4 以上にしよう ˆ 脆弱性残ったままなので危険です ˆ merciful

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

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