web-dev-qa-db-ja.com

PHP Webアプリケーションを機密情報を競合他社に公開せずに安全にデバッグするにはどうすればよいですか?

最近プログラムを作りました。 2行のコードを削除するのを忘れました。その間違いは私に毎日800ドルの費用がかかりました。

私はPHPでプログラミングをしていました。訪問者がプロキシを使用している場合、別の場所にリダイレクトされます。一部のコードにはioncubeが含まれているため、デバッガーの使用は不可能でした。プログラムはどこにでもリダイレクトするだけなので、コードのどの部分が実行されるかを確認することは困難です。

だから私はどこにでもたくさんのデバッグ情報を置いた。とにかく後者を削除するつもりだった。

もちろん、デバッグする最も自然な方法は、デバッグ情報をファイルに入れることです。問題は、私がプロキシをよく使用することです。そのため、プログラムを変更した後、filezillaを使用してテキストファイルをダウンロードする必要があります。多くの場合、テキストファイルには、表示する必要があると思われるものが表示されません。最後に、Webにエラーを表示することにしました。

デバッグモードを考えた。ただし、デバッグ情報の削除は忘れてしまいます。

たとえば、ユーザーが?debuggingmode = 1を実行する場合、デバッグモードを使用することを検討しました。しかし、どういうわけか私の競争相手は秘密のキーワードを推測することができるという妄想に悩まされました。

ほとんどのデバッグ情報を削除しました。 1つは削除するのを忘れて、その1つは、ユーザーが適切な国のプロキシを使用している場合にのみ表示されます。私は正しい国からの代理人がいないことがわかり、それを認識していませんでした。プログラムが24時間動作した後、それをメインドメインにアップロードしました。

私のライバルは、プロキシを使用して、デバッグコードを参照してください。彼はアイデアをコピーし、それが私が1日あたり$ 800を失った方法です。

振り返ってみると、どこが間違っていたのか本当にわかりません。私は細心の注意を払っています。それでも起こった。

PHP Webアプリケーションを機密情報を競合他社に公開せずに安全にデバッグするにはどうすればよいですか?

11
user114310

どこが間違っているのか本当にわからない

主な間違いは、ホイールを再発明したことです。 ロギングにデフォルトのメカニズムを使用する代わりに、ページ内に情報を表示する独自のを発明しました。ロギングフレームワークでは、ログをログファイルに保存するので、後でサーバーにSSH接続することでログを参照できます。

バグに関しては、バグのないコードを生成することは、正式な証明などの特定の手法を使用することを意味します。それらの高価さを考えると、これらの技術は航空機の交通やスペースシャトルを制御するアプリケーションなどの生命に関わるアプリケーションに適していますが、 ほぼ すべてのビジネスアプリケーション。

■Fast Companyマガジンの彼らは正しいものを書くを参照してください。
この記事では、NASAで使用されている方法論と、この方法でソフトウェアを作成するコストについて説明します。

Mechanizing Proof(Mackenzie 2004)を参照してください。
この本は、ソフトウェアの自動プルーフの歴史を要約し、そのようなプルーフの長所と短所を説明するとともに、企業が信頼性の高いソフトウェアを作成するために一般的に使用されない理由を説明しています。

そうは言っても、ソフトウェア品質を確保するためにビジネスアプリケーションで使用されるテクニックはたくさんあります。これらには以下が含まれますが、これらに限定されません。

  • 非公式のコードレビュー、
  • 正式なコード検査、
  • テスト、
  • コードのパーソナルデスクチェック
  • 等.

Code complete(McConnell 2004)、Programming Productivity(Jones 1986a)、Software Defect-Removal Efficiency(Jones 1996)、およびDefecting Fighting Defects(Shull et al。2002)。

また、継続的インテグレーションと継続的デリバリーを忘れないでください。コードレビューやユニットテストで見逃された問題が修正版にあるように見えても、本番環境のアプリを正常に機能しているバージョンに自動的にロールバックするのに役立ちます。

安全な継続的展開の秘訣 (ビデオ)を参照
デプロイ前に発見できなかったバグが本番環境に長時間留まらないようにするためにGoogleで設定された手法について説明しています。また、pdiffについても説明し、プレゼンテーション層とは無関係のバグを含め、どのようにしてバグをキャッチしたかについても説明します。

37

本番環境ではデバッグしないでください。

常に本番環境と同じテスト環境を用意し、そこでデバッグする必要があります。

テスト環境でコードを変更する必要がある場合(デバッグステートメントを追加する場合など)は、それらが本番環境に移行しないようにする必要があります。

通常、プロのセットアップは次のようになります。

Production
   ^
Staging
   ^
Development

アプリケーションの「プロダクション」、「ステージング」、および「開発」のインスタンスは、「プロダクション」で発生したバグを「ステージング」および「開発」で再現できるようにできるだけ同一にする必要がありますが、完全に分離されている必要があります。 1つのインスタンスで発生したことが他のインスタンスに影響を与えないようにするためです。

問題を分析する必要がある場合は、「開発」で行います。デバッグステートメントをいじって、必要なすべてを試してください。解決策を見つけたら、「ステージング」で未修正のコードベースにその修正を適用し、修正が機能することを確認します。次に、修正を「プロダクション」にプロモートします。

適切なバージョン管理とビルド管理システムがそれを支援します。

13
Philipp

努力する価値がないので、これはめったに行われません。 1日800ドルを失ったとしても、プログラムが正しいことを証明するための労力はすぐにそれより大きくなるため、それを行うビジネスケースがないことを意味します。

is相当の価値がある場合(スペースシャトルソフトウェアやミサイル制御など)、正式な検証、すべての可能な入力の徹底的なテストなどを実行します。当然、非常に難しいだけでなく、低速で高価です。しかし、10億ドルの予算を持つプロジェクトは、非常に優秀な人材を雇用する傾向があります。 (または、多分彼らは単に慣れました-今日の見出しはそのルールに矛盾しているようです。)

4
Kilian Foth

ライブシステムをデバッグする必要がある場合もあります。はい、開発用またはステージング用のコピーが必要です。しかし、常に違いがあります。これは、顧客のハードウェアでコードが実際に不足している場合に特に当てはまります。または潜在的に、多くの異なる顧客のインストール。

私は過去に&debugging = 1テクニックを使用しました。私はほとんどのPHP=開発者が持っていると思います。これにより、アプリケーションでより詳細なデバッグを可能にするコードのスイッチが反転しました。その情報は通常、ログファイルにダンプされます-通常、Apacheログ(error_logを使用) ())。しかし、それを出力することもできます。たとえば、プロファイラーは情報を収集し、ページの下部にさまざまなベンチマークを出力します。デバッグ情報をHTMLコメントとして、またはページのソースを表示する場合にのみ表示可能な非表示要素。

サイトに「ユーザー」がいる場合、デバッグを特定のユーザーのみに制限できます。この方法では、誰かがデバッグを有効にしようとした場合でも、そのユーザーとしてログインしない限り機能しません。

これで、FileZillaを使用してサーバーに接続すると説明しました。開発者は本当にサーバーへのSSHアクセスが必要です。これにより、デバッグがはるかに簡単になります。たとえば、Apacheエラーログにデバッグステートメントを出力する場合、そのファイルにIPアドレスを簡単にgrepし、最後のページリクエストによって生成されたデバッグ情報を確認できます。

2
GrandmasterB

他の誰もがすでに一般的なケースをカバーしています:

正式な検証(/実証済みのコード):正式に証明された4000行のOSカーネルがありますが、実際のプログラムには適していません。ロシアのCS PhD学生が何ヶ月もかかりました(このプロジェクトの名前を覚えておいてください)

CIテスト << 自動テスト << テスト:カバレッジツールを使用して、テストケースのカバレッジが100%であることを確認してください。

デバッグコードを本番環境に残すという特定のケースでは、2つのオプションがあります。どちらの場合も、新しい(ステージング/最終テスト)環境への展開の一部としてソースコードを再コンパイルする必要があります。

  1. コンパイル時に削除してください。デバッグコードをC#やC #ifdef DEBUGなどの構造にラップして、ビルドターゲット(デバッグまたはリリースのいずれか)を確認し、コンパイル時にそれらを自動的に削除します。

  2. デプロイ時にフラグを立てます。実際の環境で実行してはならないコードの近くにコメントを付けてください。例://TODO: Remove This Before Deployment、次に、ステージングに移行(デプロイ)したときに、コードをコンパイルする前に、フラグコメント(例://TODO:)が残っていないことを確認する簡単なスクリプトを実行します。ソースコード。

前者はそれが長期的でもう一度必要になる場合(例:冗長ロギングモード)、後者はデバッグ中の簡単なハック(例:コード全体に散在するさまざまなprintf)の場合に推奨します

1
Lyndon White

他の人が私の前に言ったように、可能であれば自動化され、コードが十分にカバーされている多くのテスト(単体テストと機能テスト)が、ほとんどバグのないソフトウェアを使用するための鍵です。

問題の説明を十分に理解できれば、サーバーが提供するページにデバッグ情報が表示されます。その場合は、その情報をサーバーの適切なログに記録することを検討してください。これにより、「詳細」バージョンを本番環境にデプロイした場合でも、エンドユーザーには表示されません。これは、他に特別な理由がない限り、取り組んでいるプロジェクトを何でも行うのに適した方法です。

0
KevinLH

本番環境でのデバッグについて他の人が言うことは正しいです。とにかく私は時々それをやったことがあります。そして、私はあなたよりも安全な方法があると思いますが、絶対確実なものはありません。

私自身はそのような高度なセキュリティは必要ありません。ユーザーに画面上で意味不明なものをたくさん見てほしくありません。

$debug = true;
$allowed_ips = array('192.168.0.220','173.46.89.255'); // limit to your own ip's. If your competitor knows them, though, he can spoof it! But if your stuff is not top secret, it's ok. 

if(!in_array($_SERVER['REMOTE_ADDR'],$allowed_ips) ) {
  $debug = false;
}

if($debug) {
  echo '<pre>' . print_r($some_variable) . '</pre>';
}

これで、ユーザーは本当に望まない限り、デバッグを見ることができなくなります。 1日あたり800ドルがこのデバッグ情報の秘密保持に依存している場合は、上記のコードは使用しないでくださいです。しかし、情報がそれほど機密でない場合、GET変数に依存したり、国全体に秘密を明かしたりするよりも、上記の方がはるかに優れています。

または、基準に基づいて印刷が許可されているかどうかをチェックするdebugクラスまたは関数を作成できます。それが私がすることです。

このようなもの:

class debug {
  public $on = false;
  public static function print($variable) {
    if($on) {
      echo '<pre>' . print_r($some_variable) . '</pre>';
    }
  }
}

debug::print($some_variable); // class checks if printing is allowed. If not, no printing occurs.

1日800ドル(開発中)になるプログラムでは、Apache mod authを使用して、サイトの任意の部分にアクセスするためのパスワードを要求し、デバッグ情報を特定のIPに制限しています。あなたの質問により、私はより良いセキュリティを検討すべきだと思います。

0
Buttle Butkus

実際、私はここで2つの追加検証を行います。 1つは、リクエストの_&debug=1_パラメータです。 "secret"ページ(できれば認証付き)の呼び出しを介して自分だけがアクティブにできる特別なセッション変数またはcookie設定を使用することもできます。

2番目の検証は、構成ファイルに一連のIPを持つ配列を含めることであり、その配列内のIPからの呼び出しのみがデバッグ機能をトリガーできます。何かのようなもの

構成内:

_$debugAllowedIPs = array('127.0.0.1', '192.168.0.1', /* add more IPs here */);
_

グローバルにアクセスできる場所に次のメソッドを設定します:

_function getClientIp() {
    if (!empty($_SERVER['HTTP_CLIENT_IP']))  return $_SERVER['HTTP_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
    return $_SERVER['REMOTE_ADDR'];
}
_

そしてあなたのコードでは次のようなものを呼び出します:

_if (in_array(getClientIp(), $debugAllowedIPs)) { /* show debug info here */ }
_

_$_SERVER['HTTP_X_FORWARDED_FOR']_の値は簡単にスプーフィングされるため、getClientIp()メソッドのコードは安全ではありませんが、質問の目的を明確にする目的に役立つはずです。

0
Thyamarkos