質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.82%

  • PHP

    12905questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • セキュリティー

    303questions

    このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

  • シェル

    186questions

    シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

  • OS

    138questions

    OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

【PHP】シェル経由について教えてください

解決済

回答 2

投稿 2016/05/02 16:59

  • 評価
  • クリップ 0
  • VIEW 619

gununu

score 237

PHPとシェルについて教えてください。

最近、OSコマンドインジェクションによる情報漏えいが多発しているので、理解しようと思い、調べております。
シェルやPHPについて知識が乏しい素人です。
ワードの誤用や質問の意図が分かり難いなどあるかと思いますが、回答いただけると幸いです。

シェルに関しては、こちらのページで確認し、シェルはカネールとの間に入って色々と作業をしているとの認識でおります。

■シェルとサーバの関係は?

シェルの役割については、何となく理解しました。
PHPに関しても、サーバー上にあるZned Engineによって処理していると理解しております。
引用ですが、PHP側に関しては、下記のようなイメージで理解しております。

イメージ説明

引用:独習PHP 第2版
※第2版からの引用ですが、2016年4月9日に新しい第3版が出ています。

上図を参考に私の方でシェルとカーネルを追加しました。

イメージ説明

【質問1】
シェルを実行する関数の利用を避けることで、OSコマンドインジェクションの対策になると「IPAの記事」に書いてあるので、Zend Engineとシェルがやり取りをしているのかと考えましたが、私の認識(上図)であっていますか?

※私が作成した図はこちらの「Cacoo」から編集も可能ですので、文章等で回答しにくい場合は、編集していただけると幸いです。

■使用する関数がシェル経由か調べるには?

先ほどの「IPAの記事」にはPHPの場合、exec(), passthru(), proc_open(), shell_exec(), system()をなるべく使わないとの記述があります。
この関数は、シェル経由するため使わない方がよいとのことかと存じます。

【質問2】
PHPマニュアルを見てもシェル経由する関数かどうか記載がありません。
どのようにすれば、シェル経由する関数なのか確認することができますか?

【質問3】
そもそも、なぜシェル経由する必要があるのでしょうか?
調べた感じでは、シェル経由する関数とシェル経由しない関数の2種類があるのかと思います。
シェル経由する関数はカネールの機能を利用しないと実現できないために、シェル経由しているということでしょうか?

ご存知の方いれば、教えてください。
よろしくお願いいたしますm(__)m

  • 気になる質問をクリップする

    クリップした質問に回答があった場合に通知・メールを受け取ることができます。

    クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

【質問1】 基本的には、ほとんどの関数はシェルを経由しません(Zend Engineから直接カーネルを呼び出します)。質問2とも重なりますが、シェル経由となるのは他のプログラムを呼び出す機能のうち、さらに一部だけです。

【質問2】PHPのマニュアルでプログラム実行関数としてまとめてあります。あと、バッククオート演算子も仲間に入ります。

【質問3】PHPから外部のプログラムを実行する際に、シェルを介することで「パイプ」や「リダイレクト」などのような出力制御ができるようになったり、「シェルスクリプト」が実行できるようになったりします。逆に言えばこれらを使わずにプログラムを実行するときにはシェル経由の意味はあまりありませんし、ましてや外部プログラムを実行しない時にはまったく関係しません。

投稿 2016/05/02 17:37

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2016/05/02 18:52

    いつも回答ありがとうございます。

    ・ググるとシェルがカーネルを覆うような関係図になっていたので、全てシェル経由するのかと勘違いしておりました。Zend Engineから直接カーネルを呼ぶこともあるんですね。シェル経由しない関数というのは、文字通りの意味なんですね。

    ・PHPマニュアルにまとめてあるのに気づきませんでした(^^;) これらの関数を利用するとき、利用されているときは、OSコマンドインジェクションの可能性があるので、対策する必要があるということですね。

    ・シェルについて知識が乏しく「パイプ」や「リダイレクト」について知りませんでした。このような機能を使うときにシェル経由するということなんですね。シェルについてもっと調べてみたいと思います。

    回答ありがとうございましたm(__)m

    キャンセル

+1

質問1や2は他の人がいい感じの回答をつけると思うので、質問3だけ。。。

そもそも、なぜシェル経由する必要があるのでしょうか?
調べた感じでは、シェル経由する関数とシェル経由しない関数の2種類があるのかと思います。
シェル経由する関数はカネールの機能を利用しないと実現できないために、シェル経由しているということでしょうか?

これは誰かから聞いたとかどこかで見たとかではない、わたしの予想というか勘というかそういうレベルのふわっとした妄言なのですが、、、(つまりソースはない)

Linux でプログラムを実行するとき、最終的に次の関数が実行されます。

  • https://linuxjm.osdn.jp/html/LDP_man-pages/man2/execve.2.html
int execve(const char *filename, char *const argv[], char *const envp[]);

つまり、次のものが必要とされます。

  • 実行ファイル名
  • コマンド引数の配列
  • 環境変数の配列

一方、PHP のような言語から外部コマンドを実行したい場合、次のようなものを指定すると思います。

  • コマンドライン文字列(実行ファイル名+複数のコマンド引数をスペースで連結したもの)

とりあえず環境変数は無視しまして・・・

前述の通り、最終的に必要なのは「実行ファイル名」と「コマンド引数の配列」なので、「コマンドライン文字列」をバラバラに分割する必要がありますが、それを行っているのがいわゆる「シェル」です。

なので、「コマンドライン文字列」を指定してコマンドを実行する場合は、大抵の場合シェルを経由します。

例えば、nodejs の child_process モジュールなどを見てみると、シェルを経由する child_process.exec は「コマンドライン文字列」を指定するのに大して、シェルを経由しない child_process.spawn では「実行ファイル名」と「コマンド引数の配列」を指定するようになっています。

PHP でもシェルを経由しない pcntl_exec は「実行ファイル名」と「コマンド引数の配列」を指定します。

つまり、「コマンドライン文字列」を指定して外部プログラムを実行できるようにするためには、シェルを経由する必要があります。

もちろん、「コマンドライン文字列」をプログラミング言語の方でバラバラに分割するようにすればシェルを経由せずに実行することも可能です。例えば Ruby などでは、一部のメタ文字を含んでいない場合は、Ruby の側で「コマンドライン文字列」を「実行ファイル名」と「コマンド引数の配列」に分割することでシェルを経由せずに実行します。

メタ文字を含まない、ということは、スペースで分割するだけで簡単にコマンドライン文字列をバラすことができるので、そのような実装になっているのだと思います(メタ文字を含む場合、シェルと同等のパーサが必要になりますし、リダイレクトやパイプなどのシェル特有の機能が出てきてしまいます)。

なお、これらの事情は Linux などの *nix 系 OS の事情であって、Windows では異なります。

Windows の場合、外部プログラムを実行するときの API は「実行ファイル名」と「コマンドライン引数(コマンド引数をスペースで繋げた文字列)」を指定します。

それどころか lpApplicationName は省略可能なので、「コマンドライン文字列(実行ファイル名+コマンド引数をスペースで繋げた文字列)」だけでも可能です。

つまり、Windows の場合はシェルを経由させなくても「コマンドライン文字列」を指定して外部プログラムを実行することが容易です。

そのため、PHP の proc_open には Windows にだけ bypass_shell というシェルを経由いないオプションがあります。

投稿 2016/05/02 18:07

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2016/05/02 18:58 編集

    いつも回答ありがとうございます。

    詳しい解説と参考サイトありがとうございます^^
    私の乏しい知識では、一部理解できないところもあるので、調べながら理解したいと思います。

    回答ありがとうございましたm(__)m

    キャンセル

  • 2016/05/12 16:41 編集

    Linux?コマンドライン?という状態だったので、下記の本を読んだら何となく理解できるようになりました^^

    + UNIXの絵本(株式会社アンク)
    + まんがでわかるLinux シス管系女子 (日経BPパソコンベストムック)

    PHPで外部コマンドを実行するときに書くコードは、必要な情報を連結して記述(メタ文字を含む)しており、この情報をバラバラにして解釈できるようにするためにシェルを経由している、または経由する必要があるということなんですね。

    逆にシェルを経由しないものは、上述した必要な情報をバラバラに記述(メタ文字を含まない)して実行しているんですね。

    語弊があるかもしれませんが、要はメタ文字を含む場合はシェルを経由しないと解釈できないので、シェルを経由し、メタ文字を含まないときはシェルを経由しないということなんですね。

    ただ、Windowsだけは特殊でメタ文字を含んでもシェルを経由しないで実行できるんですね。

    今も基本的なことは理解できていないので、誤解しているところもあると思いますが、何となく理解できた気がします^^

    わかりやすい回答ありがとうございましたm(__)m

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.82%

関連した質問

同じタグがついた質問を見る

  • PHP

    12905questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • セキュリティー

    303questions

    このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

  • シェル

    186questions

    シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

  • OS

    138questions

    OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

閲覧数の多いPHPの質問