PHP | Sicurezza per consentire i caricamenti degli utenti

7

La mia situazione:

Sto creando un'applicazione web con PHP che consente agli utenti di eseguire la scansione dei loro file alla ricerca di virus. Permette all'utente di caricare i propri file tramite il tipo di input "file" html o tramite un URL. Ho costruito con successo il lato html e PHP delle cose e gli utenti sono in grado di caricare correttamente i file sul mio server. Sto usando Windows Server 2012 R2 con IIS come mio server.

La mia domanda:

Per quanto ne sappia, c'è poca o nessuna sicurezza in atto (lato script e lato server) per evitare vulnerabilità di sicurezza / attacco sul mio sito web o, peggio, sul server stesso. Sono consapevole che gli autori di attacchi potrebbero potenzialmente caricare ed eseguire file che possono hackerare il mio server. Quindi, che cosa posso fare per provare ad eliminare questi problemi .

Cose di cui sono a conoscenza:

A causa della ricerca che ho condotto, è a mio avviso che potrei potenzialmente fare quanto segue per rafforzarmi, tuttavia queste sono tutte teorie e non ho idea di come metterle effettivamente in atto (quindi perché sono chiedendo):

  • Limitazione sui tipi di file (Sì, potrei potenzialmente bloccare i file .php, ma ad esempio - Non riesco a bloccare i file .exe comuni in quanto l'utente probabilmente scansionerebbe un eseguibile) Qual è il giusto equilibrio per questo tipo di servizio, poiché limitare troppi tipi di file rimuove solo l'usabilità

  • Archiviazione di file caricati in una diversa unità - La mia directory del sito è nell'unità C e ho un disco D vuoto che potrei usare. Come disabilito il server dall'eseguire qualcosa nell'unità specifica? Come posso impedire agli hacker di navigare su quell'unità e di eseguire i file caricati?

Cose che ho provato:

  • Ho creato una funzione per rinominare il file caricato in un hash MD5 di esso, con un ID univoco all'inizio, quindi l'utente non può identificare facilmente il file.
  • Tipo di file limitato per rimuovere i caricamenti .php? Forse ce ne sono altri che potrebbero essere validi per il mio scopo?

Conclusione:

Quindi essenzialmente, oltre alle risposte alle domande minori di cui sopra. Sto cercando un elenco di azioni che posso adottare per rafforzare l'applicazione e il server, per eliminare eventuali minacce. Grazie

Codice:

Come nota a margine, qui sotto puoi vedere il mio codice. Nel caso capiti qualcosa di serio lì dentro. O ci sono altre misure di sicurezza che possono essere aggiunte al codice:

PHP:

$upload_directory = "uploads/";
    $uploaded_file = $upload_directory . basename($_FILES["file"]["name"]);
    $upload_ok = 1;

    $image_file_type = pathinfo($uploaded_file, PATHINFO_EXTENSION);

    // check for files bigger then 8mb
    if($_FILES["file"]["size"] > 8388608){
        print "your file exceeds 8mb";
        $upload_ok = 0;
        exit();
    }

    // only allow certain file types
    if($image_file_type != "jpg" && $image_file_type != "png" && $image_file_type != "jpeg" && $image_file_type != "gif"){
        print "invalid file type";
        $upload_ok = 0;
        exit();
    }

    // upload it
    if($upload_ok != 0){
        move_uploaded_file($_FILES["file"]["tmp_name"], $uploaded_file);
    }

HTML:

<form method="post" action="index.php" enctype="multipart/form-data">

    <label>Select Desired File</label><br>
    <input type="file" name="file" id="file">

    <input type="submit" name="submit" value="Scan File"> 
</form> 
    
posta Jimmy 20.02.2015 - 17:42
fonte

3 risposte

4

Quando si tratta di consentire il caricamento di file utente, devi stare molto attento. Questo è solo un elenco di cose con cui iniziare, in cima alla mia testa:

Assicurati che i file non possano essere eseguiti dagli utenti

  • Configura il tuo PHP in modo che non consideri l'utilizzo dell'estensione del file PHP nelle cartelle in cui sono presenti i file PHP.
  • Assicurati che le autorizzazioni per i file siano impostate correttamente. Se non è necessario che i file caricati abbiano autorizzazioni di esecuzione, perché dovrebbero?

Impedire agli utenti di afferrare file arbitrari

A meno che non lo desideri anche tu, un utente non dovrebbe essere in grado di enumerare tutti i file caricati sul tuo servizio. Infatti, in base alla descrizione del servizio, non c'è motivo per cui dovrebbero mai essere in grado di scaricare nuovamente il file.

  • Fornisci ID univoci difficili da individuare nel nome del file. Molti siti utilizzano nomi di file lunghi e complessi per cose banali come le immagini per fornire metadati e impedire l'enumerazione.
  • Assicurati che il tuo sistema sia configurato per rilevare l'enumerazione. Un utente non dovrebbe essere in grado di fare migliaia di ipotesi sbagliate sul nome della risorsa. È possibile farlo tramite tabelle i.p, fail2ban, IDS, applicazione, database. Dipende da molte cose e molti modi per andare.
  • Se gli utenti non hanno mai bisogno di recuperare il file dal server, assicurati che sia portato in un posto dove non è possibile accedervi direttamente (come al di fuori di webroot.)
  • Considerare l'hosting dei file su un server diverso rispetto ad altre parti dell'applicazione (come la logica di business e così via.)

Garantire che i file non causino problemi direttamente per il tuo sistema

Descrivi il tuo servizio come servizio di scansione antivirus. Quello che stai cercando di fare potrebbe essere pericoloso. Non è inconcepibile che un virus possa sfruttare l'AV stesso per aumentare i privilegi.

  • Esegui una scansione di base per determinare la validità del file prima di inviarlo ad AV. Gli utenti non dovrebbero essere in grado di inviare file gravemente maciullati che potrebbero causare il crash dell'AV.
  • Controlla le intestazioni.
  • Utilizza programmi come fileinfo.
  • Verifica le informazioni sul tipo di file noto.
  • scansione del file per ovvi tentativi di mangling / fuzzing. Ad esempio, un file riempito con 10 mila caratteri A potrebbe testare il tuo sistema.

Garantire che l'AV non causi un problema

  • assicurati di utilizzare un software AV affidabile che sia completamente aggiornato e aggiornato.
  • Assicurarsi che il software AV abbia i diritti appropriati e non esponga le porte non necessarie.

Isolamento del sistema in caso di violazione

  • Ancora, assicurati che il sistema che contiene i file abbia diritti minimi.
  • Prova a utilizzare un contenitore / jail / sandbox di qualche tipo per limitare l'efficacia di un tentativo di exploit.
risposta data 20.02.2015 - 19:27
fonte
3

Quando il file viene caricato, ti suggerisco di usare finfo per determinare cosa tipo di file, indipendentemente dall'estensione del file ed esegui azioni specifiche a seconda del risultato.

Se decidi che la cartella di caricamento dovrebbe trovarsi da qualche parte nella root dei documenti, ti consiglio di disabilitato l'esecuzione di file PHP per quella cartella specifica.

Preferisco usare un algoritmo di hashing più strong per rinominare i file combinati con una stringa casuale per file. Il modo in cui descrivi il modo in cui vuoi rinominare i tuoi file sembra abbastanza prevedibile e io come attaccante proverei cose del genere per indovinare il nome del file.

    
risposta data 20.02.2015 - 18:30
fonte
-3

Una tecnica minore che ho usato è la seguente. Ho avuto un pezzo di codice C che ho scritto che esamina i primi 4-8 byte di qualsiasi file e identifica il tipo. Poiché C era vicino a PHP, ho portato quella routine in PHP. In qualche altro codice PHP ho confrontato quel tipo con l'estensione. Se c'è una discrepanza, ad es. un'estensione JPG è in realtà un file EXE Microsoft, l'ho rifiutato. Questo è importante da fare perché una classe di semplicistici exploit di Windows che comportano la creazione di un file EXE come un file immagine o qualcos'altro che l'utente è in grado di fare doppio clic.

    
risposta data 20.02.2015 - 19:13
fonte

Leggi altre domande sui tag