Ich schreibe ein Perl-Skript, wo der Benutzer eine Regex und eine Ersatzzeichenfolge eingeben kann. Das Skript durchsucht eine Reihe von Dateien und wendet Änderungen entsprechend dem Perl-Operator s///
an, der mit der Benutzereingabe angewendet wurde.Den ee-Modifizierer sicher mit dem Operator s /// verwenden, wenn die rechte Seite vom Benutzer eingegeben wird
Um die Angelegenheit leicht zu komplizieren, darf die Ersetzungszeichenfolge Rückreferenzen enthalten, um auf Erfassungsgruppen in der Regex zu verweisen. Wenn die Regex beispielsweise b(.*?)a
lautet und die Ersetzungszeichenfolge a$1b
lautet, sollte die $1
nicht wörtlich behandelt werden, sondern eher als Rückreferenz, um die erste Gruppe zu erfassen.
In dieser Einstellung, ich frage mich, ob es möglich ist, den ee
Verwendung des Änderungs sicher mit dem s///
Operator (die Rückreferenzierungen in der Benutzereingabe zu bewerten), wenn die rechte Seite dieses Operators Eingabe durch den Benutzer ist? Zum Beispiel:
use strict;
use warnings;
my $str = 'abaaca';
my $replacement = 'do{ use Env qw(HOME); unlink "$HOME/important.txt" }';
$str =~ s/a(.*?)a/$replacement/gee;
würde unglücklich sein .. Aber dann bekam ich die Idee, die Benutzereingabe zu zitieren (legt es in einem Paar doppelter Anführungszeichen) nach entkam doppelten Anführungszeichen und Dollar-Zeichen (nicht mit einer Nummer) und dann tun Ersatz:
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;
Für mich auf den ersten Blick scheint zu funktionieren, oder habe ich etwas verpasst? Zum Beispiel, wenn das Skript test.pl
genannt, und der Benutzer läuft es wie:
$ test.pl 'do{ "a$b" }'
der Ausgang nur eine einfache Zeichenfolge wie gewünscht (und kein Code ausgewertet wird):
do { „a $ b "} do {" a $ b "}
Die Frage ist also: Ist das wirklich ein sicherer/korrekter Ansatz?
Wenn der Benutzer Ihr Skript einfach auf einem Computer ausführt, auf den er bereits Zugriff hat, warum konnten sie es dann nicht einfach bearbeiten, um die bösen Dinge zu tun, die sie wollten? Oder schreiben Sie ihr eigenes Perl-Skript, das böse Dinge tut? – ThisSuitIsBlackNot
Sicher, das ist ein guter Punkt .. aber ich habe über den Fall nachgedacht, wo der Benutzer zufällig etwas eintippte, was dazu führte, dass Code im 's ///' Operator ausgeführt wurde.und das könnte unerwünschte Folgen haben –