ファイル内の危険な関数をチェックするスクリプトを作成したい

このQ&Aのポイント
  • PHPファイル内で危険な関数、非推奨になった関数が含まれているかをチェックするスクリプトを作成したい。
  • php.iniにてdisable_functionsを使用する方法もありますが、対処が必要な場合に使用したいです。
  • スマートに書く方法を知りたいです。ファイルに結果を整形して出力したいです。
回答を見る
  • ベストアンサー

ファイル内検索関数を作りたいのですが・・・

質問させて下さい。 PHPファイル内で危険な関数、非推奨になった関数が含まれているかをチェックするスクリプトを考えています。 php.iniにてdisable_functionsを使用すればいいのでしょうが、急に非推奨になったり、 コード規約で省かれたりと言った時に対処するような場合に使用したいと思っております。 コマンドラインから利用しようと思っているのですが、ここでは簡略化の為に引数を取って、1ファイル(check.php)のみに適用させています。 で、以下のように書いてみたのですが、全くエレガントな感じがしません。 自分としては、ファイルにHTMLに<table>にて整形したものを出力したいと考えています。 「どの関数が、どの行に、いくつあるのか」(フォルダを再帰的に調べる場合はパスも含める) 等を出力したいと考えています。 ((search.php) #!/usr/local/bin/php -q <?php $file = $argv[1]; if (!$file) { die('このスクリプトは引数にphpファイルのパスを必要とします。'); } //この中に該当する関数を書き入れる $functions = array( 'preg_match', 'chdir', 'settype', 'system', ); function checkFunc ($line, $functions, $n = 1) { foreach ($functions as $func) { if (strpos($line, $func) === FALSE) { continue; } else { echo($n . '行目に、' . $func . '()が含まれています。' . PHP_EOL); } } } $handle = fopen($file, 'r'); $r = 1; while ($line = fgets($handle, 1024)) { checkFunc($line, $functions, $r); $r++; } fclose($handle); ((check.php)) <?php $string = 'Hello, this is Tom. I love apple'; preg_match('/.*(apple)$/i', settype($string, 'string'), $result); var_dump($result); var_dump(getcwd()); chdir('../'); var_dump(getcwd()); もうちょっとスマートに書きたいのですが、アドバイスを頂けないでしょうか? 自分としてはecho()で出力していくのではなく、「どの関数が、どの行に、いくつあるのか」を貯めていって、 Smartyの変数にassign()で格納し出力といった感じにしたいと思っているのですが、 「どのファイルに」「何行目」、「どの関数が」、「何個」という各変数の扱い方(格納の仕方)が分かりませんでした。 Linux,PHP5.3.8です。

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • 1minn
  • ベストアンサー率57% (52/90)
回答No.2

> ここでは例として、PHPの関数のみの質問として書かせていただきましたが、汎用性を考えております。 って事はやはりひっかけたい文字列は独自に定義するしかないって事ですかね? で、あれば言語ごとにひっかけるワードをどっかで定義する必要がありそう。 (てっとり早くテキストファイルとか) キーワード自体のチェックは別に今のままでよいんじゃないかと思います。 ただ、同じ行にひっかけたい関数が複数あると、二つ目以降が気付かれなくなっちゃうかも。 なので2重にループしてやる必要がありそうですね。 で、ひっかかった時に連想配列に「どのファイルに」「何行目」、「どの関数が」、「何個」って情報をセットしとけばいいんじゃないでしょうか? if ( isset ($array[ $funcName ]) ) {   $array[ $funcName ]['length']++;   $array[ $funcName ][ $array[ $funcName ]['length'] ] = array(     'fileName' => ファイル名,     'line' => 行番号   ); } else {   $array[ $funcName ] = array(     'length' => 1,     0 => array(       'fileName' => ファイル名,       'line' => 行番号     )   ); } って感じの配列でも作って入れとけばよさそうな気がしますが・・・ あとは出来上がった配列をassignして、テンプレート側でforeachでもすりゃよさそうな気がします。

chopperin
質問者

お礼

ありがとうございます。 参考になりました。 一応、もうちょっと自分で試行錯誤してみます。

その他の回答 (1)

  • 1minn
  • ベストアンサー率57% (52/90)
回答No.1

コードの細かい部分は置いといて・・・ このやり方だと、ひっかけたい関数やらを自分で定義しなきゃいけないんですよね? あくまで非推奨なってる関数を・・・ って話ならあえてnoticeを吐き出させてそれを取得する仕組みを考えてみるのもいいのかな~と思いました。 ただ、chdirもsettypeも別に非推奨じゃないけど、これは「危険な関数」なんですか? 「chdir」「system」はコマンド実行につながるのでなんとなくわからなくもないんですが、settypeって危険なの? 「preg_match」は危険って意味もわからないし、非推奨でもない。 > php.iniにてdisable_functionsを使用すればいいのでしょうが、急に非推奨になったり、 > コード規約で省かれたりと言った時に対処するような場合に使用したいと思っております。 コード規約ってのは、内部ルールみたいなものでしょうから、分からなくはないんですが、「急に非推奨」ってのはどういう事でしょうか? 誰かが気がつかないうちにPHPのバージョンを変えたりするかな? > 自分としてはecho()で出力していくのではなく、「どの関数が、どの行に、いくつあるのか」を貯めていって、Smartyの変数にassign()で格納し出力といった感じにしたいと思っているのですが SmartyってCUIで使えるんですか?

chopperin
質問者

お礼

>>1minnさん ここであげた関数は、ただの例です。 説明不足ですみません。 HITするかしないかだけに使いました。 自分が使っていたスクリプトの一部を使い、同じ行に複数HITする関数があるかを調べるためにsettypeなど入れました。 >SmartyってCUIで使えるんですか? これまた失礼しました。 CUIでは使えません。 字数を考えたり、急いで書いたせいか、説明を大幅に省いて書いてしまいました。 CUIの例文は動くかどうかの練習用でして、自分はディレクトリ全部を検索し、全てをあるファイルに「どこに何が・・・」とか格納し、そのファイルを読み込んで別のスクリプトによって表を・・・と考えていました。 例文の示し方と文章の説明がめちゃくちゃで申し訳ないです。 >誰かが気がつかないうちにPHPのバージョンを変えたりするかな? バージョンが上がった際にテスト環境を作り、その際エラー等が出たり、非推奨になった関数をって意味でした。 PHPなく、Smartyにせよフレームワークにせよ、特定の関数、定数などを検索したいと思いまして。 Smartyを例に挙げると、2と3では結構変わってる部分もありますので、それをテンプレート、Smartyのライブラリを含めてと思っています。 sedとかでもいいのですが、自分がPHPの方が書きやすいのでこちらにしました。 ここでは例として、PHPの関数のみの質問として書かせていただきましたが、汎用性を考えております。 文章の説明が悪くて本当に申し訳ないです。

関連するQ&A

  • スクリプトの中から使用されている変数と関数をリストする

    phpで書かれたスクリプトファイルの中から使用されている関数と変数をリストアップさせるようなことをしたいのですが、preg_matchを使うのが妥当でしょうか?また、正規表記はどんな感じがベストでしょうか?自分で試してみてもまったくへたくそでして... トホホ ぜひ皆さんの技量を拝見させてください ^^。 <?php $data = file_get_contents('~.php'); $functions = '/\s*\(*/i'; preg_match($functions, $data, $matches); print_r($matches); echo "<br>"; $variables = '/^\$[.+]/i'; preg_match($variables, $data, $matches2); print_r($matches2); echo "<br><br>"; echo $data; ?>

    • ベストアンサー
    • PHP
  • PHPのpreg_replaceについて

    文字列に半角、全角があったら''に置換したいです。 例)あ あ あ -> あああ 上記のように。 ソースは下記のとおりしてみたのですがうまく表示されませんでした。 $string = 'あ あ あ'; $pattern = '[ \t\n\r\f]'; $replacement = ''; $var_dump(preg_replace($pattern,$replacement, $string)); 他には $string = 'あ あ あ'; $pattern = '[[:space:]]'; $replacement = ''; $var_dump(preg_replace($pattern,$replacement, $string)); などと行ってみました。 ご教授お願いいたします。

    • 締切済み
    • PHP
  • コードエラーが次のように出てしまいます。

    Notice: Undefined offset: 2 in C:\xampp\htdocs\news2.php on line 18 Warning: file_get_contents(): Filename cannot be empty in C:\xampp\htdocs\news2.php on line 19 プログラミング超初心者です。var_dumpしてみてもarray[2]は存在していたのですが・・・。 なぜこのようなエラーが出るのか、またどのように解決すればよいのでしょうか。わかる方、教えてください。よろしくお願いします。 <?php $newstop="http://headlines.yahoo.co.jp/hl"; $html=file_get_contents($newstop); $patern1='/http.*c=bus/'; preg_match($patern1,$html,$matches1); //var_dump($matches1); $newstop2=($matches1[0]); $html2=file_get_contents($newstop2); //echo($html2); //ここから、記事全文を拾う $fullpattern='/http.*all/'; preg_match_all($fullpattern,$html2,$matches3); $fullurl=($matches3[2]); ※ここが18行目 $fulltext=file_get_contents($fullurl);       ※ここが19行目 echo ($fulltext); //var_dump($matches3); ?>

    • 締切済み
    • PHP
  • [PHP]ループ内の配列取得、表示について

    質問させていただきます。 データをDBから取得しwhileで全てのデータを配列として出力しているとします。 (whileの中で出力し、3つのデータがあるため3回ループされている) 結果 array(1) { [0]=> string(5) "17:10" } array(2) { [0]=> string(5) "17:10" [1]=> string(5) "17:25" } array(3) { [0]=> string(5) "17:10" [1]=> string(5) "17:25" [2]=> string(5) "11:15" } 現在の出力内容は、 var_dump[$hoge[0]] 出力結果 string(5) "17:10" string(5) "17:10" string(5) "17:10" var_dump[$hoge[1]] 出力結果 NULL string(5) "17:25" string(5) "17:25" var_dump[$hoge[2]] 出力結果 NULL NULL string(5) "11:15" という出力になっていますが、最後のarray(3)の部分だけを抜き出したいです。 その場合はどのようにすればよいのでしょうか? -理想の結果- 利用したいのはarray(3)の部分だけ。 var_dump[$hoge[0]] "17:10" var_dump[$hoge[1]] "17:25" var_dump[$hoge[2]] "11:15" 説明不足かもしれませんが、よろしくお願いいたしますm(_ _)m

    • ベストアンサー
    • PHP
  • csvファイル検索

    フォームから検索文字を入力してもらい 4列、2000行ほどのcsvファイル内を検索し、ヒットしたらその行を出力するというものを作りたいと考えています。 csv  ------------------------- 1|自転車 バイク 2056,タイヤ,ペダル,ハンドル  |  ------------------------- 2|バイク 2001,タイヤ,ペダル,ハンドル      |  ------------------------- 3|自転車 バイク 2001,タイヤ,ペダル,ハンドル  |  ------------------------- 4|自転車 バイク 5601,タイヤ,ペダル,ハンドル  |  ------------------------- といった行があったとして、フォームに "自転車 56"と入力した際、 1行目3行目4行目の文字列を表示したいのですが、その際 1行目と4行目は2つヒットしているので3行目より上に表示させたいのです。 yahooなどの検索サイトのor検索のようなものです。(スペース区切り) 正規表現でやればいいのか?と思い手をつけてみたのですがどうも違うようですし、もしかしたらPHPで作ろうというのが間違っているのかもしれませんが、何か方法及び参考になるurlがありましたら教えてください。 よろしくお願いします。 windows2000 php4-4.3.8-18です。

    • 締切済み
    • PHP
  • シェルスクリプトでファイルの読みとり

    /etc/ldap.confからpam_passwordで始まる行を見つけてその行を書き換えて上書きする関数を作ろうとしているところです。 以下のようにしましたがデバッグのためのechoでの出力が見えませんでした。 echoで1行ずつ列挙されるのを確認したいのですがどうしたらよいですか? function func1 { while read LINE ; do echo $LINE done < $1 return "" } buf=`func /etc/ldap.conf`

  • 【PHP】関数で処理が止まってる??

    お世話になります。 PHPでの質問ですが、PHPに限ったものではないように思いますので、プログラム全般に対しての質問と思って下さって結構です。 ※PHP特有のという意見があれば、それも大歓迎です。 下記のようなコードを組んでみました。 <?php echo "func1の結果["; echo func1(); echo "]"; function func1(){ (内容は割愛) return TRUE; } ?> このコードをアップしてアクセスしてみると   出力結果  func1の結果[ でした。 ブラウザのステータスに「ページが表示されました」とあるので、処理中で出力待ちということはないと思います。 > echo func1(); > echo "]"; の箇所の出力はどうなっていると考えればいいのでしょうか? 「関数の内容次第で・・・」とお答えになる方、どういう内容だとこのような結果になるのかというところでお答えください。 私のプログラムによる根本的な考え方は、プログラムは上から下に順番になので、 上記内容の箇所にどんなコードがあったとしても、func1関数はTRUEを返すので、結果としては「func1の結果[1]」となるはずでした。 でも実際の出力結果をみると処理が途中で(おそらくfunc1()内で)止まっているともいます。 timeoutではないため無限ループに嵌ってっていうのもないと思います。 これはどういうことでしょう???

    • 締切済み
    • PHP
  • var_dump関数()の使い道

    PHPをイチから勉強しています。 「var_dump()関数を使うと変数の情報を表示できます」と本に載っていますが、この関数の使い道は何だろう?と疑問に思っています。解説では、 $a = true; var_dump($a); は bool(true) 論理型で値はtrueです、とあります。 でも、この関数を使わなくても見れば分かるのでは?と思い、分からなくなりました。素人爆発の質問で申し訳ないのですが分かりやすく教えてください。よろしくお願いします。

    • ベストアンサー
    • PHP
  • 【PHP】配列に出てくるこの名称はなんですか?

    PHP初心者です。 専門用語について教えてください。 $myAr[0] = 'あ'; $myAr[1] = 'い'; var_dump($myAr); としたとき、 array(2) { [0]=> string(3) "あ" [1]=> string(3) "い" } と出力されると思いますが、この[0][1]の「名称」は何でしょう? 意味はわかりますが呼び名がわからずすっきりしません。 キーじゃないですしね。 お詳しい方、よろしくお願いいたします。

    • 締切済み
    • PHP
  • PHP_INT_MAXを超える値の出力について

    下記の「希望」の値を出力させていのですが、 PHP_INT_MAXを超える値が指数表記となってしまいます。 PHPのコンパイル時に、BMP、BCMATHなどを有効にすれば希望の出力を得る関数が使えるようになるのですが、都合によりリコンパイルができません。 何か他の方法で希望の出力を得ることはできないのでしょうか。 <?php print("値は".(string)353108774858342429); // 希望 =>値は353108774858342429 // 実際 => 値は3.5310877485834E+17 var_dump(PHP_INT_MAX); // int(2147483647)

    • ベストアンサー
    • PHP

専門家に質問してみよう