2011-11-22 9 views
5

Tengo el siguiente script CGI:Cómo untaint llamada al sistema en 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 

Cuando ejecuto el comando que me da este

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

Cómo la línea 10 puede ser fijo?

Respuesta

5

Utilice el built-in grep función, por ejemplo:

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

+1. ¿Por qué usar comandos del sistema cuando hay una mejor manera de lograr el resultado deseado? – flesk

3

El interruptor -T sólo le advierte acerca de la posible entrada contaminada: http://perldoc.perl.org/perlsec.html#Taint-mode

Es necesario untaint por sí mismo, por ejemplo usando

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

Sin embargo, esa no es una prueba muy sofisticada, y posiblemente tampoco demasiado segura, a menos que tenga c control total sobre lo que coincide con \w.

EDIT: Cambié mi solución mínima para reflejar la información dada en los comentarios a continuación.

+1

O haga alguna coincidencia como: my ($ untaint_data) = $ td = ~ m/^ \ s * (\ w +) \ s * $/;. – XoR

+4

La sustitución no establece un valor. Solo la asignación de un grupo de expresiones regulares capturadas ('($ no contaminado) = $ contaminado = ~/(patrón) /;', '$ corrompido = ~/(patrón) /; $ no contaminado = $ 1;') liberará una expresión. Consulte "Laundering and Detecting Tainted Data" en ['perlsec'] (http://search.cpan.org/perldoc?perlsec). – mob

+0

@mob: Gracias por la información. +1. – flesk

3

Creo que el problema aquí es que el operador de backtick está ejecutando efectivamente el código fuera del entorno perl, y por lo tanto no es de confianza, es decir. contaminado.

Se podría, por supuesto, tratar de hacer algo como esto antes de que la línea en cuestión:

$ENV{"PATH"} = ""; 

Es probable que aún así obtener un error de esta línea:

my $file = "justafile.txt"; 

Para corregir esto, se probablemente podría simplemente darle una ruta absoluta, por ejemplo:

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

Es casi seguro que tenga que dé una ruta absoluta al comando grep que está ejecutando con el operador de backtick también, ya que borrar las variables de entorno perderá la ruta. En otras palabras, hacer:

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

También puede ser que desee para copiar el valor de $ENV antes de borrarlo, en caso de que necesite más adelante ...

esperanza alguna de que esto ayude!

+2

Error conceptual: los datos están contaminados, no la operación realizada en ellos. Vea la salida de: 'perl -T -MDevel :: Peek -e'Dump \ @ARGV '" Juro solemnemente que no estoy haciendo nada bueno ". – daxim

8

El punto principal de la contaminación es garantizar que la entrada no verificada no pueda suministrarse a funciones potencialmente inseguras.

En este caso, su variable $searchterm podría contener entradas inesperadas que podrían permitirle a un atacante ejecutar programas arbitrarios en su sistema.

Por lo tanto, o hay que hacer:

  1. untaint la variable asegurando que coincida con una expresión regular predeterminada (ver @ respuesta de Flesk), momento en el que Perl supone que sabe lo que 'doing, o

  2. no use los apoyos (por la respuesta de @eugene y).

Si está utilizando acentos abiertos también se debe especificar la ruta completa al comando grep de manera que usted no está en función de $PATH.

Cuestiones relacionadas