2015-03-17 12 views
5

Sto scrivendo uno script Perl in cui l'utente può immettere un'espressione regolare e una stringa sostitutiva. Lo script cercherà un set di file e applicherà le modifiche secondo l'operatore perl s/// applicato con l'input dell'utente.Utilizzando il modificatore ee in modo sicuro con l'operatore /// quando viene immesso il lato destro dall'utente

Per complicare leggermente le cose, la stringa di sostituzione può contenere riferimenti secondari per fare riferimento ai gruppi di cattura nella regex. Ad esempio, se l'espressione regolare è b(.*?)a e la stringa di sostituzione è a$1b, lo $1 non deve essere trattato letteralmente, ma deve essere considerato come riferimento per acquisire il gruppo numero uno.

In questo contesto, mi chiedo se è possibile utilizzare il modificatore ee (per valutare i riferimenti all'indietro nel input dell'utente) in modo sicuro con l'operatore s/// quando il lato destro di questo operatore è di input da parte dell'utente? Per esempio:

use strict; 
use warnings; 
my $str = 'abaaca'; 

my $replacement = 'do{ use Env qw(HOME); unlink "$HOME/important.txt" }'; 

$str =~ s/a(.*?)a/$replacement/gee; 

sarebbe un peccato .. Ma poi ho avuto l'idea di citare l'input dell'utente (metterlo dentro un paio di virgolette doppie) dopo avere doppi apici sfuggiti e segni di dollaro (non seguito da un numero), e poi do sostituzione:

use feature qw(say); 
use strict; 
use warnings; 

my $str = 'abaaca'; 

my $replacement = shift; 
$replacement =~ s/\"/\\\"/g; 
$replacement =~ s/\$(?!\d)/\\\$/g; 
$replacement = '"' . $replacement . '"'; 
$str =~ s/a(.*?)a/$replacement/gee; 
say $str; 

a me questo sembra funzionare a prima vista, o hanno ho perso qualcosa? Per esempio, se lo script si chiama test.pl e l'utente lo esegue come:

$ test.pl 'do{ "a$b" }' 

l'output è lo desideri basta una semplice stringa (e nessun codice è valutata):

fare { "un $ b "} do {" a $ b "}

Quindi la domanda è: questo è davvero un approccio sicuro/corretto?

+0

Se l'utente sta semplicemente eseguendo il tuo script su una macchina a cui hanno già accesso, perché non potrebbero semplicemente modificarlo per fare qualsiasi cosa diabolica volessero? O, del resto, scrivi il loro script Perl che fa cose cattive? – ThisSuitIsBlackNot

+0

Certo, questo è un buon punto ... ma stavo pensando al caso in cui l'utente ha digitato per errore qualcosa che ha provocato l'esecuzione del codice nell'operatore 's ///'.e questo potrebbe avere conseguenze indesiderate –

risposta

5

Problema 1:

Non c'è modo di sostituire con $1 seguita da 1 dal momento che le segue sostituisce con ${1}1.

$ script '${1}1' 
${1}1${1}1 

Problema 2:

$ script '\${ system "echo rm -rf /" }' 
rm -rf/
Use of uninitialized value in substitution iterator at a.pl line 12. 
rm -rf/
Use of uninitialized value in substitution iterator at a.pl line 12. 

Problema 3:

$ script '$1{ system "echo rm -rf /" }' 
rm -rf/
Use of uninitialized value within %1 in string at (eval 1) line 1. 
rm -rf/
Use of uninitialized value within %1 in string at (eval 2) line 1. 

Sicuramente, ci sono altri. Soluzione:

Utilizzare String::Substitution.

+0

Grazie, sembra buono. Sembra che qualcuno abbia già risolto il mio problema .. –

+0

Come funziona effettivamente il problema 2? Se scrivo 'script '$ 1 {say" "}'' Ricevo un errore 'Uso del valore non inizializzato all'interno di% 1 nella stringa a (eval 1) riga 1.' .. Sono bloccato qui, perché ottengo questo errore messaggio, e perché dice '% 1'? –

+0

Forse se hai stampato qualcosa di diverso da una linea vuota, sarebbe più evidente che hai stampato qualcosa ... – ikegami

Problemi correlati