Wie sollte man eine PHP-Webanwendung sicher debuggen, ohne die Geheimnisse der Konkurrenz preiszugeben?


11

Kürzlich habe ich ein Programm gemacht. Ich habe vergessen, 2 Codezeilen zu löschen. Dieser Fehler kostete mich jeden Tag 800 Dollar pro Tag.

Ich habe mit PHP programmiert. Wenn ein Besucher einen Proxy verwendet, leitet er ihn an eine andere Stelle weiter. Die Verwendung des Debuggers war nicht möglich, da ein Teil des Codes ioncube enthält. Da das Programm einfach irgendwo anders umleitet, ist es schwer zu erkennen, welcher Teil des Codes ausgeführt wird.

Also habe ich überall eine Menge Debugging-Informationen veröffentlicht. Ich dachte, ich werde sie trotzdem löschen.

Der natürlichste Weg zum Debuggen besteht natürlich darin, Debugging-Informationen in eine Datei einzufügen. Das Problem ist, dass ich oft Proxy benutze. Nachdem ich das Programm geändert habe, muss ich die Textdatei häufig mit filezilla herunterladen. Oft zeigt die Textdatei nicht, was ich denke, dass es zeigen sollte. Schließlich habe ich beschlossen, nur Fehler im Web anzuzeigen.

Ich dachte über einen Debugging-Modus nach. Ich fürchte jedoch, ich werde vergessen, Debugging-Informationen zu löschen.

Ich habe überlegt, den Debugging-Modus zu verwenden, wenn der Benutzer beispielsweise? Debuggingmode = 1 ausführt. Ich war jedoch paranoid, dass mein Konkurrent das geheime Schlüsselwort irgendwie erraten kann.

Ich habe die meisten Debugging-Informationen gelöscht. Ich habe vergessen, einen zu löschen, und dieser wird nur angezeigt, wenn Benutzer einen Proxy aus dem richtigen Land verwenden. Es stellte sich heraus, dass ich keinen Vertreter aus dem richtigen Land habe und das nicht realisiert habe. Nachdem das Programm 24 Stunden lang funktioniert hat, habe ich es auf meine Hauptdomain hochgeladen.

Mein Konkurrent, der Proxy verwendet, sieht den Debugging-Code. Er kopiert die Idee und so habe ich 800 Dollar pro Tag verloren.

Rückblickend fällt es mir wirklich schwer zu sehen, wo ich falsch gelaufen bin. Ich war sehr vorsichtig. Trotzdem ist es passiert.

Wie sollte man eine PHP-Webanwendung sicher debuggen, ohne die Geheimnisse der Konkurrenz preiszugeben?


5
Es gibt nichts, was absolut sicher ist, geschweige denn fehlerfreie Software.
Tar

1
Nach jeder Änderung am Programm / der Anwendung immer wieder gründlich testen, auch wenn es sich um eine sehr kleine Änderung handelt.
Rolen Koh

16
"Wie sollte man eine Webanwendung sicher debuggen, ohne die Geheimnisse der Konkurrenz preiszugeben?" - indem Sie eine Testumgebung erstellen, die Ihre Produktionsumgebung nachahmt. Live-Debugging sollte eigentlich sehr selten notwendig sein.
CodeCaster

8
Ich frage mich, was an zwei Zeilen Debugging-Code so kritisch sein kann, dass er 800 US-Dollar pro Tag wert ist. Gibt es Ihren privaten crpytografischen Schlüssel aus?
Philipp

2
Wenn Sie vorher eine Weile über 800 Dollar pro Tag verdient haben ... spielt das überhaupt eine Rolle? Aber ja, setzen Sie den Debug-Code nicht live ein! Sie könnten einen booleschen Konfigurations-Debug-Modus in einer Datei haben. Lassen Sie den Debug-Code nur drucken, wenn debug == true ist. Dies ist zumindest ein schneller und schmutziger Weg, der es nicht wert ist, eine Antwort zu sein!
Anon343224user

Antworten:


37

Es fällt mir wirklich schwer zu sehen, wo ich falsch gelaufen bin

Der Hauptfehler war, dass Sie das Rad neu erfunden haben. Anstatt Standardmechanismen für die Protokollierung zu verwenden, haben Sie Ihre eigenen erfunden , die die Informationen auf der Seite anzeigen. Ein Protokollierungsframework speichert Protokolle lieber in Protokolldateien, sodass Sie diese Protokolle später per SSH an den Server abrufen können.

Was das Erstellen von fehlerfreiem Code für die Fehler betrifft, müssen bestimmte Techniken wie z. B. formale Beweise verwendet werden . Aufgrund ihrer hohen Kosten eignen sich diese Techniken für lebenswichtige Anwendungen wie Anwendungen, die den Flugzeugverkehr oder Raumfähren steuern, sind jedoch für fast jede Geschäftsanwendung ein Overkill .

■ Siehe Sie schreiben das richtige Zeug in der Zeitschrift Fast Company.
Der Artikel beschreibt die bei der NASA verwendete Methodik sowie die Kosten für die Herstellung von Software auf diese Weise.

■ Siehe Mechanizing Proof (Mackenzie 2004).
Das Buch fasst die Geschichte des automatisierten Proofs von Software zusammen und erläutert die Vor- und Nachteile eines solchen Proofs sowie die Gründe, warum Unternehmen ihn nicht häufig zum Schreiben zuverlässiger Software verwenden.

Abgesehen davon gibt es eine Reihe von Techniken, die für Geschäftsanwendungen verwendet werden, um die Softwarequalität sicherzustellen. Dazu gehören unter anderem:

  • Informelle Codeüberprüfungen,
  • Formale Code-Inspektionen,
  • Testen,
  • Persönliche Überprüfung des Codes am Schreibtisch,
  • usw.

■ Siehe Code vollständig (McConnell 2004), Programmierproduktivität (Jones 1986a), Effizienz bei der Beseitigung von Softwarefehlern (Jones 1996) und Was wir über die Bekämpfung von Fehlern gelernt haben (Shull et al. 2002).

Vergessen Sie auch nicht die kontinuierliche Integration und kontinuierliche Lieferung. Es hilft dabei, die App in der Produktion automatisch auf eine funktionierende Version zurückzusetzen, wenn bei einer überarbeiteten Version ein Problem auftritt, das bei Codeüberprüfungen und Komponententests übersehen wurde, aber nach der Bereitstellung der App abgefangen wurde.

■ Siehe Das Geheimnis einer sicheren kontinuierlichen Bereitstellung (Video)
Hier wird erläutert, welche Techniken bei Google eingerichtet wurden, um zu verhindern, dass Fehler, die vor der Bereitstellung nicht gefunden wurden, zu lange in der Produktion verbleiben. Es wird auch beschrieben pdiffund wie es verwendet wurde, um Fehler zu erkennen, einschließlich solcher, die nicht mit der Präsentationsschicht zusammenhängen.


13

Sie sollten niemals in der Produktion debuggen.

Sie sollten immer eine Testumgebung haben, die mit der Produktionsumgebung identisch ist, und dort debuggen.

Wenn Sie Code in der Testumgebung ändern müssen (z. B. zum Hinzufügen von Debugging-Anweisungen), sollten Sie sicherstellen, dass diese nicht in die Produktion gehen.

Ein professionelles Setup sieht normalerweise so aus:

Production
   ^
Staging
   ^
Development

Die Instanzen "Production", "Staging" und "Development" Ihrer Anwendung sollten so identisch wie möglich sein, damit ein Fehler, der in "Production" auftritt, in "Staging" und "Development" reproduziert werden kann, aber dennoch vollständig von diesen getrennt ist einander, so dass alles, was in einer der Instanzen passiert, die anderen nicht beeinflusst.

Wenn Sie ein Problem analysieren müssen, tun Sie dies in "Entwicklung". Spielen Sie mit Debug-Anweisungen und experimentieren Sie mit allem, was Sie wollen. Wenn Sie eine Lösung gefunden haben, wenden Sie diesen Fix auf die unveränderte Codebasis in "Staging" an und überprüfen, ob der Fix funktioniert. Dann fördern Sie den Fix auf "Produktion".

Ein ordnungsgemäßes Versionskontroll- und Build-Management-System kann Ihnen dabei helfen.


1
Das ist, was ich tat. Ich debugge zuerst in anderen Domänen. Danach gehe ich zu den neuen über. Der Fehler in dieser anderen Domain war jedoch immer noch vorhanden.
user114310

1
@ user114310, Ihre Entwicklungs- / Testumgebung sollte für die Außenwelt einfach nicht zugänglich sein (entweder auf localhost oder VPN erforderlich oder ähnlich). Wenn Sie einen Debug-Code eingefügt und ihn nicht entfernt haben, bevor Sie zur Produktion übergegangen sind, ist dies ein menschlicher Fehler, und es gibt nichts Technologisches, das davor schützen kann. Sei einfach vorsichtiger.
Brian S

3
@ user114310 Entschuldigung, ich verstehe nicht. Sie haben den Fehler beim Staging behoben, aber als Sie diesen Fix auf die Produktion angewendet haben, war der Fehler immer noch vorhanden? Das würde bedeuten, dass Sie den Fehler nicht korrekt reproduziert und versehentlich etwas anderes behoben haben. Wenn Sie einen Fehler in der Entwicklung nicht reproduzieren können, bedeutet dies, dass Ihre Entwicklungsumgebung nicht mit der Produktionsumgebung identisch ist. Wenn Sie feststellen, dass Sie dies zuerst beheben müssen, bevor Sie den Fehler richtig untersuchen können.
Philipp

4

Dies wird selten durchgeführt, da sich der Aufwand nicht lohnt. Selbst wenn Sie 800 US-Dollar pro Tag verlieren, wird der Aufwand, ein Programm korrekt zu beweisen, schnell größer, was impliziert, dass es keinen Business Case dafür gibt.

Wenn sicher zu sein , ist so viel wert (zB für Space Shuttle Software oder Raketensteuerung), dann führen Sie die formale Verifikation, erschöpfende Prüfung aller möglichen Eingaben etc. Zugegeben, es ist auch sehr schwierig , wie auch langsam und teuer. Projekte mit Milliardenbudgets haben aber auch extrem kluge Leute. (Oder vielleicht haben sie es einfach früher getan - heutige Schlagzeilen scheinen dieser Regel zu widersprechen.)


1
Sogar die NASA versteht es falsch. Sie können sich so viel Mühe geben, wie Sie möchten, aber einige Dinge sind einfach nicht nachvollziehbar und daher sehr, sehr schwer zu gewährleisten.
Phoshi

1
+1: Formale Überprüfung ist eine Sache. Es wäre gut, wenn Sie näher darauf eingehen könnten. Ich weiß, dass es eine Sache ist, aber ich habe nicht die Worte, um mehr Details zu finden. ZB Überprüfung durch Testen aller Eingaben, Reduktion auf endliche Statemaschine, Reduktion auf Logik erster Ordnung. Was ist das Wort dafür? Ist diese Überprüfung durch Beweise? Ich denke, es ist.
Lyndon White

Es gibt eine formale Überprüfung, aber auch eine heuristische Überprüfung, die zwar nicht sicher ist, jedoch eine Überprüfung bis zu einem bestimmten Konfidenzniveau ermöglichen kann. Ich erinnere mich nicht viel an das Thema vom College, aber ein Werkzeug, das wir im Kurs verwendet haben, war Spin, von dem ich glaube, dass es auch eine umfassende Überprüfung ermöglicht. Einige der Beschreibungen könnten darauf antworten, was das richtige Wort ist.
Rig

2

Manchmal müssen Sie ein Live-System debuggen. Ja, Sie sollten eine Entwicklungs- oder Staging-Kopie haben. Aber es wird immer Unterschiede geben. Dies gilt insbesondere dann, wenn der Code auf der Kundenhardware in freier Wildbahn ausgeht. Oder möglicherweise viele verschiedene Kundeninstallationen.

Ich habe in der Vergangenheit die Technik & debugging = 1 verwendet. Ich vermute, die meisten PHP-Entwickler haben. Dadurch wurde ein Schalter im Code umgelegt, der ein ausführlicheres Debuggen in der Anwendung ermöglichte. Diese Informationen werden normalerweise in eine Protokolldatei geschrieben - im Allgemeinen in das Apache-Protokoll (mit error_log ()). Sie können es aber auch ausgeben. Unser Profiler würde beispielsweise Informationen sammeln und dann die verschiedenen Benchmarks am Ende der Seite ausgeben. Sie können die Debugging-Informationen auch als HTML-Kommentar oder in einem versteckten Element ausgeben, das nur angezeigt werden kann, wenn Sie die Seitenquelle anzeigen.

Wenn Ihre Site "Benutzer" hat, können Sie das Debuggen nur auf einen bestimmten Benutzer beschränken. Auf diese Weise funktioniert jemand, der versucht, das Debuggen zu aktivieren, immer noch nicht, es sei denn, er ist als dieser Benutzer angemeldet.

Nun haben Sie erwähnt, dass Sie FileZilla verwenden, um eine Verbindung zum Server herzustellen. Ein Entwickler sollte wirklich SSH-Zugriff auf den Server haben. Das erleichtert Ihnen das Debuggen erheblich. Wenn Sie beispielsweise Ihre Debugging-Anweisungen in das Apache-Fehlerprotokoll ausgeben, können Sie diese Datei problemlos nach Ihrer IP-Adresse durchsuchen und die Debugging-Informationen anzeigen, die durch Ihre letzte Seitenanforderung generiert wurden.


1

Alle anderen haben den allgemeinen Fall bereits behandelt:

Formale Validierung (/ Bewährter Code): Nicht realisierbar für Programme der realen Welt, obwohl es ein 4000-Zeilen-Betriebssystem gibt, das formal bewiesen wurde. Es hat viele, viele russische CS-Doktoranden viele Monate gedauert (bitte kommentieren, wenn Sie sich an den Namen dieses Projekts erinnern).

CI-Tests << Automatisierte Tests << Tests : Stellen Sie sicher, dass Sie ein Abdeckungstool verwenden, um zu überprüfen, ob Ihre Testfälle eine 100% ige Abdeckung aufweisen.

Für Ihren speziellen Fall, Debug-Code in der Produktion zu belassen, stehen zwei Optionen zur Verfügung. Für beide muss der Quellcode im Rahmen der Bereitstellung in einer neuen Umgebung (Staging / Final Testing) erneut ergänzt werden.

  1. Entfernen Sie es beim Kompilieren. Wickeln Sie Debug-Code in Strukturen wie C # und C ein #ifdef DEBUG, um das Build-Ziel (entweder Debug oder Release) zu überprüfen und sie beim Kompilieren automatisch zu entfernen.

  2. Markieren Sie es zur Bereitstellungszeit. Fügen Sie einen Kommentar in die Nähe von Code ein, der nicht in der realen Umgebung ausgeführt werden darf. Beispiel //TODO: Remove This Before Deployment: Wenn es dann nach Staging migriert (bereitgestellt) wird, führen Sie es vor dem Kompilieren des Codes durch ein einfaches Skript, das überprüft, ob //TODO:im Quellcode keine Flag-Kommentare (z. B. ) mehr vorhanden sind .

Ich schlage das erstere vor, wenn es langfristig ist und Sie es wieder wollen (z. B. ausführlicher Protokollierungsmodus), und das letztere, wenn es ein schneller Hack ist, während Sie debuggen (z. B. verschiedene printfs, die über Ihren Code verstreut sind).


0

Wie andere vor mir gesagt haben, sind viele Tests (Einheit und Funktion), wenn möglich automatisiert und mit guter Codeabdeckung, der Schlüssel zu einer größtenteils fehlerfreien Software.

Wenn ich die Beschreibung Ihres Problems gut genug verstehe, werden die Debugging-Informationen auf der von Ihrem Server bereitgestellten Seite angezeigt. In diesem Fall sollten Sie in Betracht ziehen, diese Informationen in die richtigen Protokolle auf Ihrem Server aufzunehmen. Auf diese Weise wird es dem Endbenutzer nie angezeigt, selbst wenn Sie eine ausführliche Version für die Produktion bereitstellen. Dies ist etwas, das Sie tun können, unabhängig davon, an welchem ​​Projekt Sie arbeiten, es sei denn, Sie haben sehr gute Gründe, etwas anderes zu tun.


0

Was andere über das Debuggen in der Produktion sagen, ist richtig. Aber ich habe es trotzdem manchmal gemacht. Und ich denke, es gibt sicherere Möglichkeiten als Ihre, obwohl nichts narrensicher ist.

Ich brauche selbst keine so hohe Sicherheit, ich möchte nur nicht, dass Benutzer eine Menge Kauderwelsch auf ihren Bildschirmen sehen.

$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>';
}

Jetzt sehen Benutzer Ihr Debugging nur dann, wenn sie es wirklich wollen. Wenn Ihre $ 800 / Tag davon abhängen, diese Debug-Informationen geheim zu halten, verwenden Sie den obigen Code nicht . Wenn die Informationen jedoch nicht so vertraulich sind, ist das oben Genannte viel besser, als von einer GET-Variablen abhängig zu sein oder Ihre Geheimnisse einem ganzen Land preiszugeben.

Alternativ können Sie eine debugKlasse oder Funktion erstellen , die anhand Ihrer Kriterien prüft, ob das Drucken zulässig ist oder nicht. Das ist, was ich tue.

Etwas wie das:

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.

Für mein Programm, das mir (in der Entwicklung) 800 US-Dollar pro Tag einbringt, verwende ich Apache Mod Auth, um ein Kennwort für den Zugriff auf einen beliebigen Teil der Site zu benötigen und Debug-Informationen auf bestimmte IP-Adressen zu beschränken. Ihre Frage lässt mich denken, ich sollte mich um eine bessere Sicherheit kümmern.


0

Eigentlich hätte ich hier zwei zusätzliche Validierungen. Einer ist der &debug=1Parameter in der Anfrage. Sie können auch eine spezielle Sitzungsvariable oder ein Cookie-Setup verwenden, die nur Sie über einen Aufruf einer "geheimen" Seite aktivieren können (vorzugsweise mit Authentifizierung).

Die zweite Validierung wäre, in der Konfigurationsdatei ein Array mit einem Bereich von IPs zu haben, und nur Aufrufe von einer IP in diesem Array können die Debugging-Funktionalität auslösen. etwas wie

In der Konfiguration:

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

Haben Sie irgendwo die folgende Methode, auf die global zugegriffen werden kann:

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'];
}

Und in Ihrem Code rufen Sie so etwas auf wie:

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

Bitte beachten Sie, dass der Code in der getClientIp()Methode nicht sicher ist, da der Wert für $_SERVER['HTTP_X_FORWARDED_FOR']leicht gefälscht werden kann. Er sollte jedoch dem Zweck dienen, den Punkt für Ihre Frage zu vermitteln.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.