2014-11-29 16 views
8

Komut satırından gelen tek satırların security implications numaralı perl çalıştırılıyor.Perl'i komut satırından çalışırken her zaman açık üç argüman formu kullanabilir miyiz?

$ perl -pe '' 'uname|' 
Linux 

Veya daha tehlikeli:

sorun seçenek dosyalarının adı özel karakterler içeriyor öylesine, perl beklendiği gibi çalışmıyor, open iki argüman formu kullanın elmas operatörü <>, tetikleyecek -n/-p olmasıdır > ile başlayan dosyalar, >file gibi. Bu durumda, dosya kesilecektir. bu konuyla etrafında çalışma için

, biz: CPAN

  • kullanın ARGV::readonly modülü.
  • kendimiz tarafından ARGV::readonly modül gibi özelliğini uygulayın:

perl -pe 'BEGIN{$_.="\0" for @ARGV} ...' ./* 

  • Kullanım -i seçeneği, perl dosya işleme konulmasından önce var olup olmadığını kontrol edecektir olarak.
  • Tonlama modunu etkinleştirmek için -T seçeneğini kullanın.

Tüm çözümlerin bu sorunu çözebileceğini düşünüyorum, ancak bunların yan etkileri de var. perl'u zorlayabilirsek, her zaman open argüman formunu kullanın, daha iyi bir çözüm olacaktır.

Bunu yapabiliriz, zorla perl her zaman open argüman formunu kullanın?

Not

(tabii ki) biz her zaman Perl komut open üç argüman formu kullanabilirsiniz, çünkü komut satırından perl bir gömlekleri çalıştırırken soru yalnızca durum için geçerlidir.

alias perl='perl -MARGV::readonly' 

Ya da sadece "kötü" oneliners yazarak insanları eğitmek:

+0

demek istediğini anlıyorum ama 'perl -pe 'Uname |' '' çıktısı nasıl görmüyorum' insanlar ne beklenir değildir ve olurdu büyük tehlikenin "perl -pe" 1 ""> myfile "olduğunu düşündüm. Bence bütün komut satırı giriş dosyaları, her zaman '<' olarak ayarlanmış olan ikinci parametre ile üç parametreli form kullanılarak açılmalıdır. – Borodin

+0

@Borodin: 'uname | '' yerine geçerli bir dosya adıdır, yerine' uname 'komutu çalıştırılır ve' perl 'olarak adlandırılır. Ve bu komutun rm -rf $ HOME' olabileceğini görüntüleme. Evet, -i 'seçeneği dışında, dosyayı yerinde düzenlemek istediğinizde. Daha fazla bilgi için soruma verdiğim bağlantıyı okuyabilirsiniz. – cuonglm

cevap

2

Önceki cevabımda, ARGV filehandle sihrinin 2 argümanını açık olarak öykünür ama aslında Perl'in yerleşik open işlevini gerçekleştirmediğini varsaydım. Bu yüzden biraz daha araştırdım ve sanırım bu soruna gerçek bir çözüm buldum.

doio.c'daki Perl_nextargv işlevi, perl'in ARGV dosya tanıtımı etrafında G/Ç gerçekleştirir.

Bu işlevin while döngüsünde, dosya tanıtımı açmak için iki tür çağrı vardır. LIKELY(PL_inplace) doğru olduğunda (yani, perl, -i anahtarıyla çalıştırıldığında), çağrı do_open_raw olur. LIKELY(PL_inplace) yanlış olduğunda, arama do_open6 içindir. Bu ikinci çağrı, genel olarak OP'nin istemediği harici komutlara borular açabilir.

Yani burada çözüm: Kaynak dosyada doio.c yılında, do_open_raw ile Perl_nextargv olanlar do_open6 çağrısı (ler) değiştirin ve kaynağından perl yeniden. perl-5.22.0, orijinal kod

if (LIKELY(!PL_inplace)) { 
     if (nomagicopen 
       ? do_open6(gv, "<", 1, NULL, &GvSV(gv), 1) 
       : do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0) 
      ) { 
      return IoIFP(GvIOp(gv)); 
     } 
    } 

benziyor ve değişmiş kod the new <<>> syntax from perl 5.22.0 kullandığınızda

if (LIKELY(!PL_inplace)) { 
     if (do_open_raw(gv, PL_oldname, oldlen, O_RDONLY, 0)) { 
      return IoIFP(GvIOp(gv)); 
     } 
    } 

(nomagicopen parametre doğrudur gibi. Ben sadece ayarlayın sanırım görünüyor fonksiyonun üst kısmında true'a ve başka herhangi bir şeyi değiştirmek zorunda değilsiniz, ancak yukarıdaki değişiklik eski perllerin genel çözümlerinden biridir).

Örnek çıktı:

$ original-perl -pe '' a b c 'date|' 
Can't open a: No such file or directory 
Can't open b: No such file or directory. 
Can't open c: No such file or directory. 
Mon Sep 21 18:41:37 PDT 2015 

$ modified-perl -pe '' a b c 'date|' 
Can't open a: No such file or directory. 
Can't open b: No such file or directory. 
Can't open c: No such file or directory. 
Can't open date|: No such file or directory. 
+0

+1. Merak ediyorum neden hala iki argüman formu kullanıyorsun? '<' 'Değişiyor '<<>> gibi davranıyor mu? – cuonglm

+0

Perl, bu yüzden, muhtemelen bu davranışa bağlı olan komut dosyaları var. Belki bir gün biz -N 've -P-'-n' ve '-p' gibi komut dizilerini '(<<>>) {...}' ile değiştiririz. – mob

1

Sen alias birlikte ARGV::readonly kullanabilirsiniz.

+0

Üzgünüz, düzeltildi. –

+1

Veya 'PERL5OPT ortam değişkenine' -MARGV :: readonly' ekleyebilirsiniz – mob

4

Muhtemelen sadece tek katlı (-e anahtarını kullanarak) yapmak istiyorsunuz, bu nedenle bu amaç için ARGV::readonly'u özelleştirmek istersiniz.

Bu paketin sistem genelinde kullanılmasını zorlamak için, takma ad kullanarak Patrick J.S.'yi kullanabilirsiniz.

alias perl='perl -MSanitize::ARGV' 

anlaşılacağı veya sistem genelinde PERL5OPT değişken

PERL5OPT="-MSanitize::ARGV" 

ayarlamak Ve daha paranoyak olmak istiyorsanız, sistem perl gizlemek (anlaşılmaz bir şeye yeniden adlandırmak) ve bir sarıcı

ile değiştirin
#!/bin/bash 
THE_REAL_PERL=/usr/bin/glorbqweroinuerqwer 
$THE_REAL_PERL -MSanitize::ARGV "[email protected]" 

kabuk sargı hala PERL5OPT

012 herhangi bir kullanıcı özelleştirme işlemleri olacak

Genel durumda, CORE::GLOBAL mekanizmasını yerleşik open işlevini geçersiz kılmak için kullanabilirsiniz.

package SafeOpen; 
use Carp; 
BEGIN { 
    *CORE::GLOBAL::open = sub (*;[email protected]) { 
     goto &CORE::open if @_ > 2; 
     Carp::cluck("OH MY GOD USING THE TWO-ARG open ARE YOU LIKE INSANE?"); 
     return CORE::open($_[0], '<', $_[1] // $_[0]); 
    }; 
} 
1; 

ve bu modül kullanımdayken bir 2-arg open çağrısı kullanarak eylemi kimseyi yakalayacak. Ne yazık ki, ARGV filehandle sihrinin mekanizmasının bunu atladığını düşünüyorum, bu yüzden hala tek linerdaki komut satırındaki goofy dosya adlarında yardımcı olmaz.

+0

Evet, 'ARGV'yi denetlemenin yollarını biliyorum. Benim sorum şu ki 'perl' açık üç argümanı kullanmaya zorlamak için var mı? – cuonglm

+0

“CORE :: GLOBAL :: open” altını kurabilirsiniz (ve sorununun çözülüp çözülmeyeceğini görmek için denedim), ama “ARGV” mekanizmasının sihri atlattığını düşünüyorum. – mob

+0

Eh, benim soruda bahsettiğim buydu. Ve sanırım 'CORE :: GLOBAL :: open' adlı bir etkisi yok. '-n' ve '-p' düğmesi, 'open' iki argüman formunu kullanan elmas işlecini tetiklediğinden beri. 'Perl' kaynağını kesmek için – cuonglm

İlgili konular