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


11

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

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

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

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

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

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

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

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

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

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


5
バグのないソフトウェアは言うまでもなく、何かについて絶対に確信しているようなものはありません。
Tar

1
プログラム/アプリケーションが非常に小さな変更であっても、変更が加えられるたびに何度も何度も徹底的にテストします。
Rolen Koh

16
「競合他社に秘密を公開せずに、Webアプリケーションを安全にデバッグするにはどうすればよいですか?」-本番環境を模倣したテスト環境を作成する。ライブデバッグが必要になることはほとんどありません。
CodeCaster 14年

8
2行のデバッグコードについて、1日あたり$ 800に相当するほど重要なものは何なのでしょうか。秘密の暗号鍵をダンプしますか?
フィリップ

2
あなたがこれまでしばらくの間一日に800ドル以上稼いでいたなら...それは重要ですか?ただし、デバッグコードをライブに配置しないでください。ファイルにconfigデバッグモードのブール値を含めることができます。debug == trueの場合にのみ、デバッグコードを出力します。これは少なくとも迅速で汚い方法であり、回答する価値はありません!
Anon343224user 2014年

回答:


37

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

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

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

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

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

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

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

完全なコード(McConnell 2004)、プログラミングの生産性(Jones 1986a)、ソフトウェアの欠陥除去効率(Jones 1996)、および欠陥との闘いについて学んだこと(Shull et al。2002)を参照してください。

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

安全な継続的導入の秘訣(ビデオ)参照してください。導入
前に発見できなかったバグが本番環境に長時間留まらないようにするためにGoogleで設定された手法について説明しています。またpdiff、プレゼンテーションレイヤーに関係のないバグを含め、バグの検出にどのように使用されたかについても説明します。


13

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

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

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

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

Production
   ^
Staging
   ^
Development

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

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

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


1
それが私がしたことです。最初に他のドメインでデバッグします。その後、新しいものに移動します。ただし、その別のドメインのバグはまだ残っていました。
user114310 2014年

1
@ user114310、開発/テスト環境は外部からアクセスできないようにする必要があります(localhost上にあるか、VPNが必要か、など)。デバッグコードを挿入し、本番環境に移行する前に削除しなかった場合、それは人為的なエラーであり、それを保護できる技術はありません。単にもっと注意してください。
ブライアンS

3
@ user114310すみません、わかりません。ステージングでバグを修正しましたが、その修正を実稼働環境に適用したとき、バグはまだ残っていましたか?これは、バグを正しく再現せず、誤って他の何かを修正したことを意味します。開発中のバグを再現できない場合は、開発環境が本番環境と同一ではないことを意味します。バグを適切に調査する前に、まず修正する必要があることがわかった場合。
フィリップ

4

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

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


1
NASAでさえそれを間違っています。あなたは好きなだけ努力をすることができますが、いくつかのことは単に人間の理解を超えているため、保証することは非常に困難です。
Phoshi

1
+1:正式な検証は重要なことです。それについて詳しく説明できるとよいでしょう。それが問題であることは知っていますが、詳細を見つけるための言葉がありません。たとえば、すべての入力をテストすることによる検証、有限状態機械への削減、一次論理への削減。これの言葉は何ですか?これは証明による検証ですか?それはそうですね。
リンドンホワイト

正式な検証がありますが、確実ではありませんが、特定の信頼レベルの検証を提供できるヒューリスティックな検証もあります。大学のトピックについてはあまり覚えていませんが、このコースで使用したツールの1つはSpinでした。徹底的な検証も可能だと思います。それに関する説明のいくつかは、正しい単語が何であるかを答えるかもしれません。
リグ

2

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

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

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

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


1

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

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

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

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

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

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

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


0

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

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


0

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

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

$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

実際には、ここで2つの追加の検証があります。1つは&debug=1リクエストのパラメータです。特別なセッション変数または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 */ }

getClientIp()の値$_SERVER['HTTP_X_FORWARDED_FOR']は簡単に偽装されるため、メソッドのコードは安全ではないことに注意してください。ただし、これは、質問の要点をつかむ目的に役立つはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.