2011-11-22 15 views
5

Ho il seguente script CGI:Come untaint chiamata di sistema in CGI.pm

#!/usr/bin/perl -T 
use strict; 
use warnings; 
use CGI::Carp qw(fatalsToBrowser); 
use CGI qw/:standard/; 
my $query = CGI->new(); 
my $searchterm = param('name'); 

my $file = "justafile.txt"; 
# Begin searching terms and ignoring case 
my @entries = `grep -i \"$searchterm\" $file`; # Line10 
chomp @entries; 
# Do something 

Quando eseguire il comando mi dà questa

Insecure dependency in `` while running with -T switch at /foo/cgi-bin/mycode.cgi line 10. 

Come linea 10 può essere fisso?

risposta

5

Utilizzare il built-in grep funzione, per es:

open my $fh, '<', $file or die $!;  
my @entries = grep /$searchterm/i, <$fh>; 
+4

+1. Perché utilizzare i comandi di sistema quando c'è un modo migliore per ottenere il risultato desiderato. – flesk

3

L'interruttore -T avverte solo possibile ingresso contaminato: http://perldoc.perl.org/perlsec.html#Taint-mode

È necessario untaint da soli, ad esempio utilizzando

my $safe_searchterm = ""; 
$safe_searchterm .= $_ for $searchterm =~ /\w+/g; 

Questo non è un test molto sofisticato però, e probabilmente neanche troppo sicuro, a meno che non si abbia controllo incompleto su quali corrispondenze \w.

MODIFICA: Modificata la mia soluzione minima per riflettere le informazioni fornite nei commenti seguenti.

+1

Oppure alcuni corrispondenti come: my ($ untaint_data) = $ td = ~ m/^ \ s * (\ w +) \ s * $/;. – XoR

+4

La sostituzione non elimina un valore. Solo l'assegnazione da un gruppo di espressioni regolari catturate ('($ untainted) = $ tainted = ~/(pattern) /;', '$ tainted = ~/(pattern) /; $ untainted = $ 1;') staccherà un'espressione. Vedi "Lavaggio e rilevamento di dati contaminati" in ['perlsec'] (http://search.cpan.org/perldoc?perlsec). – mob

+0

@mob: Grazie per l'informazione. +1. – flesk

3

Penso che il problema qui sia che l'operatore backtick sta eseguendo il codice in modo efficace al di fuori dell'ambiente Perl, ed è quindi giustamente non affidabile, vale a dire. contaminato.

Si potrebbe, naturalmente, provare a fare qualcosa di simile prima della riga incriminata:

$ENV{"PATH"} = ""; 

Sarà probabilmente ancora un errore da questa linea:

my $file = "justafile.txt"; 

Per rimediare, si potrebbe probabilmente dargli un percorso assoluto, ad esempio:

my $file = "/home/blah/justafile.txt"; 

Si dovrebbe quasi certamente dare un percorso assoluto al comando grep che si sta eseguendo anche con l'operatore backtick, in quanto eliminando le variabili di ambiente si perderà il percorso. In altre parole fare:

# Begin searching terms and ignoring case 
my @entries = `/bin/grep -i \"$searchterm\" $file`; # Line10 

Si potrebbe anche voler copiare il valore di $ENV prima di cancellarne il, solo in caso di necessità in un secondo momento ...

Speranza po 'di questo aiuta!

+2

Errore concettuale: i dati sono macchiati, non l'operazione eseguita su di essi. Vedi l'output di: 'perl -T -MDevel :: Peek -e'Dump \ @ARGV '" Giuro solennemente di non avere alcuna utilità. " – daxim

8

L'intero punto di contaminazione è garantire che l'input non controllato non possa essere fornito a funzioni potenzialmente pericolose.

In questo caso, la variabile $searchterm potrebbe contenere input imprevisti che potrebbero consentire a un utente malintenzionato di eseguire programmi arbitrari sul sistema.

Quindi, è sia bisogno di:

  1. untaint la variabile facendo in modo che esso corrisponde a un regexp predeterminato (vedere @ risposta di Flesk), a questo punto Perl presuppone che si sa cosa si stai facendo, oppure

  2. non utilizzare i backtick (per la risposta di @eugene y).

se si sta utilizzando apici inversi si dovrebbe anche specificare il percorso completo per il comando grep in modo che non sei a seconda $PATH.

Problemi correlati