sed PHP exec fonksiyonu ile çalışmıyor

3 Cevap php
echo "sed -i 's/NULL/\\N/g' ".$_REQUEST['para'].".sql";

Yukarıdaki açıklamalarımızın çalışır. Ama bu böyle exec kullandığınızda başarısız ...

exec("sed -i 's/NULL//\/\/\N/g' ".$_REQUEST['para'].".sql");

3 Cevap

Sen böyle eğik çizgilerle, ile, ters eğik çizgi ile ters bölü kaçmak gerekir:

exec("sed -i 's/NULL/\\\\N/g' ".$_REQUEST['para'].".sql");

EDIT Ben kodu aslında ne bakmadan cevap yazdı. $_REQUEST['para'] code injection için kullanılabilecek, kullanıcının istediği her şey olabilir çünkü, bunu yapmayın. Diğer cevap anlaşılacağı gibi PHP fonksiyonları kullanın.

Bu tamamen size kalmış, ama benim tavsiyem sistem gereksiz komutları çağırmak için olmasa da. PHP, sed işlevselliğini yapmak için () preg_replace kullanabilirsiniz.

preg_replace("/NULL/","\\N",file_get_contents("$_REQUEST['para']"."sql") )

Ghostdog fikrine binaen, burada aslında (o yayınlanmıştır özgün kod aslında dosyanın içeriğini okumadım) ne istediğinizi yapacak kodu:

//basename protects against directory traversal
//ideally we should also do a is_writable() check   
$file = basename($_REQUEST['para'].".sql");
$text = file_get_contents($file); 
$text = str_replace('NULL', '\\N', $text); //no need for a regex
file_put_contents($file, $text);

Söz konusu dosya bir kaç meg daha fazla ise tüm dosya belleğe okunacak gibi, kuşkusuz, ancak bu önerilmez. Siz parçalar halinde bunu okuyabilir, ama bu biraz daha karmaşık almak istiyorum:

$file = basename($_REQUEST['para'].".sql");
$tmpFile = tempnam("/tmp", "FOO");
$in = fopen($file, 'r');
$tmp = fopen($tmpFile, 'w');
while($line = fgets($in)) {
  $line = str_replace('NULL', '\\N', $line);
  fputs($tmp, $line);
}
fclose($tmp);
fclose($in);
rename($tmpFile, $file);

Dosya 100 + meg ise, dürüst, daha hızlı olacaktır edilir gibi doğrudan sed çağırıyor. Bu büyük dosyaları söz konusu olduğunda, kendi PHP eşdeğer sed / grep gibi bir araç üretmek için çalışmakla havai sadece buna değer değil. Bunu yapmak için gidiyoruz eğer Ancak, en azından kendinizi korumak için bazı adımlar atması gerekir:

Amnom kodunu güvenliğini sağlamak için bazı temel adımlar atıyor:

$file = basename($_REQUEST['para'].".sql");
if(!is_writable($file))
  throw new Exception('bad filename');
exec("sed -i 's/NULL/\\\\N/g' ".escapeshellarg($file));
  1. First, we call basename, which strips any path from our filename (e.g., if an attacker submitted the string '/etc/passwd', we'd at least now be limiting them to the file 'passwd' in the current working directory
  2. Next, we ensure that the file is, in fact, writable. If not, we shouldn't continue
  3. Son olarak, dosya üzerinde () escapeshellarg. Aksi takdirde keyfi komut çalıştırılmasına olanak verir. örneğin, saldırgan dize gönderilirse /etc/passwd; rm -rf /; #, sen komutu ile bitirmek istiyorum sed 's/blah/blah/' /etc/passwd; rm -rf /; #.sql. Tam o komut aslında olur önemsiz bir bulgu, iş olmayabilir iken anlaşıldı olmalıdır.