Come si dovrebbe effettuare il debug di un'applicazione Web PHP in modo sicuro senza esporre i segreti ai concorrenti?

10

Recentemente ho creato un programma. Ho dimenticato di cancellare 2 linee di codici. Quell'errore mi è costato $ 800 al giorno ogni giorno.

Stavo programmando con PHP. Se un visitatore utilizza il proxy, reindirizza da qualche altra parte. Usare il debugger era impossibile perché alcuni codici contengono ioncube. Poiché il programma semplicemente reindirizza da qualche altra parte, non importa cosa, è difficile vedere quale parte del codice viene eseguita.

Quindi ho messo un mucchio di informazioni di debug ovunque. Ho pensato di eliminarli comunque.

Il modo più naturale per eseguire il debug è ovviamente quello di inserire informazioni di debug in un file. Il problema è che uso spesso il proxy. Quindi, dopo aver cambiato il programma, devo spesso scaricare il file di testo con filezilla. Spesso il file di testo non mostra quello che penso dovrebbe mostrare. Alla fine ho deciso di visualizzare solo l'errore sul web.

Ho considerato di avere la modalità di debug. Tuttavia, temo che dimenticherò di cancellare le informazioni di debug.

Ho considerato di avere la modalità di debug se l'utente fa? debuggingmode = 1 per esempio. Tuttavia, ero paranoico che in qualche modo il mio concorrente potesse indovinare la parola chiave segreta.

Ho cancellato la maggior parte delle informazioni di debug. Ho dimenticato di cancellare uno e questo si mostra solo se gli utenti utilizzano il proxy dal paese giusto. Si scopre che non ho procura dal paese giusto e non me ne sono reso conto. Dopo che il programma ha funzionato per 24 ore, l'ho caricato sul mio dominio principale.

Il mio concorrente, usando il proxy, vede il codice di debug. Copia l'idea ed è così che ho perso $ 800 al giorno.

In retrospettiva, ho davvero difficoltà a vedere dove ho sbagliato. Sono stato molto attento. Eppure è successo.

Come si dovrebbe eseguire il debug di un'applicazione Web PHP in modo sicuro senza esporre i segreti ai concorrenti?

    
posta user114310 13.01.2014 - 11:25
fonte

8 risposte

37

I really have a hard time seeing where I went wrong

L'errore principale è stato che hai reinventato la ruota. Invece di utilizzare i mecanismi predefiniti per la registrazione, hai inventato il tuo , che visualizzava le informazioni all'interno della pagina. Un framework di registrazione preferisce archiviare i log nei file di log, permettendoti di consultare tali log in un secondo momento tramite SSHing sul server.

Per quanto riguarda gli errori, la produzione di codice privo di errori implica l'utilizzo di tecniche specifiche come prova formale . Data la loro ampiezza, queste tecniche sono appropriate per applicazioni critiche per la vita come applicazioni che controllano il traffico aereo o navette spaziali, ma sono un eccesso per quasi ogni applicazione aziendale.

■ Vedi Scrivono le cose giuste in Fast Company magazine.
L'articolo descrive la metodologia utilizzata dalla NASA, così come il costo di produzione del software in questo modo.

■ Vedi Mechanizing Proof (Mackenzie 2004).
Il libro riassume la storia della prova automatica del software, spiegando i pro ei contro di tale prova, nonché i motivi per cui non è comunemente utilizzato dalle aziende per scrivere software affidabile.

Detto questo, ci sono un sacco di tecniche utilizzate per le applicazioni aziendali per garantire la qualità del software. Quelli include ma non sono limitati a:

  • recensioni informali del codice,
  • Ispezioni del codice formale,
  • Test,
  • Controllo del codice personale del codice,
  • ecc.

■ Vedi Codice completo (McConnell 2004), Programmazione della produttività (Jones 1986a), Efficienza della rimozione dei difetti del software (Jones 1996) e Cosa abbiamo imparato sui difetti di combattimento (Shull et al., 2002).

Inoltre, non dimenticare l'integrazione continua e la consegna continua. Aiuta a riportare automaticamente l'app in produzione a una versione funzionante quando una versione rivista sembra avere un problema che è stato mancato durante le revisioni del codice e il test delle unità, ma viene catturato una volta che l'app è stata distribuita.

■ Vedi Il segreto della distribuzione continua sicura (video)
Spiega quali tecniche sono stati installati su Google per evitare bug che non sono stati trovati prima che la distribuzione rimanga troppo a lungo in produzione. Descrive anche pdiff e come è stato usato per catturare bug, inclusi quelli che non erano correlati al livello di presentazione.

    
risposta data 13.01.2014 - 11:58
fonte
13

Non dovresti mai eseguire il debug in produzione.

Dovresti sempre avere un ambiente di test identico all'ambiente di produzione e eseguirne il debug.

Quando è necessario modificare il codice nell'ambiente di test (ad esempio per aggiungere istruzioni di debug), è necessario assicurarsi che non entrino in produzione.

Una configurazione professionale di solito è simile a questa:

Production
   ^
Staging
   ^
Development

Le istanze di "Produzione", "Staging" e "Sviluppo" della tua applicazione dovrebbero essere le più identiche possibili in modo che un bug che si verifica in "Produzione" possa essere riprodotto in "Staging" e "Sviluppo", ma essere comunque completamente separati gli uni dagli altri in modo che qualunque cosa accada in una delle istanze non abbia effetto sugli altri.

Quando è necessario analizzare un problema, lo si fa in "Sviluppo". Scambia le affermazioni di debug e sperimenta tutto quello che vuoi. Quando hai trovato una soluzione, applichi quella correzione alla base di codice invariata in "Staging" e verifica che la correzione funzioni. Quindi promuovi la correzione su "Produzione".

Un controllo di versione e un sistema di gestione build adeguati possono aiutarti in questo.

    
risposta data 13.01.2014 - 14:54
fonte
4

Questo è raramente fatto perché lo sforzo non è utile. Anche se perdi $ 800 al giorno, lo sforzo di provare un programma corretto diventa rapidamente più grande di quello, il che implica che non vi è alcun business case per farlo.

Se sei certo che è vale la pena (es. per il software Space Shuttle o il controllo missilistico), esegui verifiche formali, test esaustivi di tutti i possibili input, ecc. Certo, è anche estremamente difficile così come lento e costoso. Ma i progetti con budget da miliardi di dollari tendono anche ad avere persone estremamente brillanti. (O forse erano abituati a - i titoli di oggi sembrano contraddire quella regola.)

    
risposta data 13.01.2014 - 11:36
fonte
2

A volte è necessario eseguire il debug di un sistema live. Sì, dovresti avere una copia di sviluppo o di staging. Ma ci saranno sempre delle differenze. Ciò è particolarmente vero se il codice si sta esaurendo nell'hardware del cliente. O potenzialmente, molte diverse installazioni del cliente.

Ho usato la tecnica & debugging = 1 in passato. Sospetto che la maggior parte degli sviluppatori PHP abbia. Che ha capovolto un interruttore nel codice che abilita il debug più dettagliato nell'applicazione. Quelle informazioni venivano di solito scaricate su un file di log, generalmente il log di apache (usando error_log ()). Ma puoi anche produrlo. Il nostro profiler, ad esempio, raccoglierà informazioni e quindi produrrà i vari benchmark nella parte inferiore della pagina. Puoi anche inviare le informazioni di debug come commento HTML o in un elemento nascosto che è visualizzabile solo se visualizzi l'origine della pagina.

Se il tuo sito ha "utenti", puoi limitare il debug solo a un particolare utente. In questo modo, se qualcuno tenta di abilitare il debug, non funzionerà mai a meno che non abbia effettuato l'accesso come tale utente.

Ora hai detto che stavi usando FileZilla per connetterti al server. Uno sviluppatore dovrebbe davvero avere l'accesso SSH al server. Ciò renderà il debug molto più facile per te. Ad esempio, se dovessi inviare le tue dichiarazioni di debug al log degli errori di Apache, ad esempio, potresti facilmente svuotare quel file per il tuo indirizzo IP e vedere le informazioni di debug generate dalla tua ultima richiesta di pagina.

    
risposta data 13.01.2014 - 17:48
fonte
1

Tutti gli altri hanno già trattato il caso generale:

Convalida formale (/ codice comprovato): Non fattibile per i programmi del mondo reale, sebbene ci sia un sistema operativo di 4000 linee, che è stato formalmente provato, ci sono voluti molti molti studenti di dottorato CS russi per molti mesi ( per favore commenta se ricorda il nome di questo progetto)

Test CI < < Test automatico < < Test : assicurati di utilizzare uno strumento di copertura per verificare che i casi di test abbiano una copertura del 100%.

Per il tuo caso specifico di lasciare il codice di debug in produzione, Ho 2 opzioni, entrambe richiedono il codice sorgente da ricomporre come parte della distribuzione in un nuovo ambiente (Staging / Final Testing).

  1. Rimuoverlo in fase di compilazione. Avvia il codice di debug in strutture come C # e C #ifdef DEBUG per controllare il target di compilazione, (Debug o Release) e rimuoverli automaticamente al momento della compilazione.

  2. Contrassegnalo al momento della distribuzione. Metti un commento vicino al codice che non deve essere eseguito nell'ambiente reale. Ad esempio //TODO: Remove This Before Deployment , quindi quando viene migrato (implementato) in Staging, prima di compilare il codice, eseguirlo attraverso un semplice script che controlla che non ci siano commenti Flag (ad esempio //TODO: ) lasciati nel codice sorgente.

Suggerisco il primo per se è a lungo termine e lo vorrai di nuovo (es. modalità di registrazione dettagliata), e il successivo se è un trucco rapido mentre eseguivi il debug (ad esempio, vari printfs sparsi nel tuo codice)

    
risposta data 13.01.2014 - 16:41
fonte
0

Come altri hanno già detto prima di me, molti test (unitari e funzionali), se possibile automatizzati e con una buona copertura del codice, sono la chiave per avere un software per lo più privo di bug.

Se capisco la descrizione del tuo problema abbastanza bene, le informazioni di debug sono mostrate sulla pagina servita dal tuo server. In tal caso, dovresti prendere in considerazione la possibilità di inserire tali informazioni nei log appropriati sul tuo server. In questo modo non viene mai mostrato all'utente finale, anche se si distribuisce una versione "dettagliata" alla produzione. Questo è qualcosa che è buono per fare qualunque sia il progetto su cui stai lavorando, a meno che tu non abbia ottime ragioni per fare diversamente.

    
risposta data 13.01.2014 - 11:58
fonte
0

Ciò che gli altri dicono del debugging nella produzione è giusto. Ma l'ho fatto a volte comunque. E penso che ci siano modi più sicuri di farlo rispetto ai tuoi, anche se nulla è infallibile.

Non ho bisogno di un livello di sicurezza così alto, non voglio che gli utenti vedano un sacco di parole senza senso sui loro schermi.

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

Ora gli utenti non vedranno il debug a meno che non lo desiderino davvero. Se il tuo $ 800 al giorno dipende dal mantenere segrete queste informazioni di debug, allora non utilizzare il codice precedente . Ma se l'informazione non è così sensibile, quanto sopra sarà molto meglio che dipendere da una variabile GET o rivelare i tuoi segreti a un intero paese.

In alternativa, puoi creare una classe o una funzione debug che verifichi se la stampa è consentita o meno in base ai tuoi criteri. Questo è quello che faccio.

Qualcosa del genere:

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.

Per il mio programma che mi renderà $ 800 / giorno (in fase di sviluppo), utilizzo apache mod auth per richiedere una password per accedere a qualsiasi parte del sito, oltre a limitare le informazioni di debug a determinati indirizzi IP. La tua domanda mi fa pensare che dovrei cercare una sicurezza migliore però.

    
risposta data 08.04.2014 - 10:42
fonte
0

In realtà, avrei due convalide extra qui. Uno è il parametro &debug=1 nella richiesta. Puoi anche utilizzare qualche variabile di sessione speciale o configurazione di cookie che solo tu puoi attivare tramite una chiamata a una pagina "segreta" (preferibilmente con autenticazione).

La seconda convalida dovrebbe essere nel file di configurazione, una matrice con un intervallo di IP e solo le chiamate da un IP in quell'array possono attivare la funzionalità di debug. qualcosa come

Nella configurazione:

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

Avere il seguente metodo da qualche parte dove è possibile accedervi globalmente:

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

E nel tuo codice chiama qualcosa come

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

Tieni presente che il codice nel metodo getClientIp() non è sicuro poiché il valore per $_SERVER['HTTP_X_FORWARDED_FOR'] è facilmente falsificato, tuttavia dovrebbe servire allo scopo di ottenere il punto per la tua domanda.

    
risposta data 08.04.2014 - 11:34
fonte

Leggi altre domande sui tag