2014-11-29 8 views
8

Uruchamianie perl jednoosobowe z wiersza poleceń ma security implications.Czy możemy wymusić, aby perl zawsze używał trzech argumentów otwartych przy uruchamianiu z wiersza poleceń?

Problem polega na tym, że opcje -n/-p wywołać operatora diament <>, które wykorzystują dwa argumenty formę open, więc z nazwy plików zawierają znaki specjalne, perl nie działa zgodnie z oczekiwaniami:

$ perl -pe '' 'uname|' 
Linux 

lub więcej niebezpiecznych gdy nazwa pliku zaczyna się od >, np. >file. W takim przypadku plik zostanie obcięty.

Do prac wokół z tego problemu możemy:

  • Zastosowanie ARGV::readonly moduł z CPAN.
  • Wdrożenie funkcji, takich jak moduł ARGV::readonly przez Nas:

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

  • Zastosowanie -i opcji, jak perl sprawdzi plik istniał przed przetworzeniem go.
  • Użyj opcji -T, aby włączyć tryb taint.

Myślę, że wszystkie rozwiązania mogą rozwiązać ten problem, ale także mają swoje skutki uboczne. Jeśli będziemy w stanie wymusić perl zawsze użyjemy tej argumentacji w postaci open, będzie to lepsze rozwiązanie.

Zastanawiam się, czy możemy to zrobić, wymusić perl zawsze używać argumentów z formularza open?

Uwaga

Pytanie zastosowanie wyłącznie do przypadku, gdy uruchomiony perl jeden wkładki z linii poleceń, ponieważ (oczywiście) zawsze możemy użyć trzy formy argument open w skrypcie Perla.

+0

rozumiem twój punkt widzenia, ale nie widzę w jaki sposób wyjście 'perl -pe„”„uname |”' nie jest to, co ludzie oczekują, i musiałby uważam, że większym niebezpieczeństwem jest "perl -pe" 1 ""> mójplik "'. Myślę, że wszystkie pliki wejściowe wiersza poleceń powinny zostać otwarte przy użyciu formularza z trzema parametrami, a drugi parametr zawsze ustawiony na '<'. – Borodin

+0

@Borodin: ''uname |'' jest poprawną nazwą pliku, zamiast go otworzyć, polecenie 'uname' jest wykonywane i potokować do' perl'. I obrazując, że polecenie może być 'rm -rf $ HOME'. Tak, z wyjątkiem opcji "-i", jeśli chcesz edytować plik w miejscu. Możesz przeczytać link podany w moim pytaniu, aby uzyskać więcej szczegółów. – cuonglm

Odpowiedz

2

W mojej poprzedniej odpowiedzi, postawiłem hipotezę, że filehandle magic na emulatorze 2-argumentowym jest otwarta, ale w rzeczywistości nie przechodzi przez funkcję wbudowaną Perla w open. Więc zbadałem to jeszcze trochę i myślę, że wymyśliłem rzeczywiste rozwiązanie tego problemu.

Funkcja Perl_nextargv w doio.c gdzie Perl wykonuje I/O wokół ARGV uchwytu pliku.

Wewnątrz pętli tej funkcji istnieją dwa rodzaje wywołań do otwierania uchwytów plików. Gdy LIKELY(PL_inplace) jest prawdziwe (to jest, gdy perl jest uruchamiany z przełącznikiem -i), wywołanie to do_open_raw. Gdy LIKELY(PL_inplace) ma wartość false, połączenie ma numer do_open6. To drugie wywołanie jest w stanie otworzyć rury na polecenia zewnętrzne, co w zasadzie nie jest potrzebne w PO.

Więc oto rozwiązanie: w pliku źródłowym doio.c wymienić te do_open6 połączenia (y) w Perl_nextargv z do_open_raw i odbudować perl od źródła. Na perl-5.22.0, oryginalny kod wygląda

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)); 
     } 
    } 

a kod zmieniony wygląda

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

(parametr nomagicopen prawda podczas korzystania the new <<>> syntax from perl 5.22.0. Chyba moglibyśmy po prostu ustawić go do true w górnej części funkcji i nie trzeba zmieniać niczego innego, ale powyższa zmiana jest ogólnym rozwiązaniem dla starszych wersji Perla).

wyjście

Próbka:

$ 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 za włamanie do źródła 'perl'. Zastanawiam się, dlaczego "perl" wciąż używa dwóch argumentów? Czy zmiana '<>' zachowuje się jak '<<>>' czy można zsynchronizować wstecz? – cuonglm

+0

To Perl, więc tak, są prawdopodobnie scenariusze, które zależą od tego zachowania. Może któregoś dnia będziemy mieć przełączniki '-N' i' -P' jak '-n' i' -p', które zawijają skrypt w 'while while (<<>>) {...}'. – mob

1

Można użyć ARGV::readonly w połączeniu z alias:

alias perl='perl -MARGV::readonly' 

Albo po prostu edukować ludzi, że są wpisując „złych” oneliners.

+0

Przepraszam, poprawiłem. –

+1

Lub możesz dodać '-MARGV :: readonly' do zmiennej środowiskowej' PERL5OPT' – mob

4

Prawdopodobnie chcesz zrobić to tylko dla jednopanelowych (przy użyciu przełącznika -e), więc w tym celu musisz dostosować ARGV::readonly.

package Sanitize::ARGV; 
if ($0 eq '-e') { 
    @ARGV = map { # from ARGV::readonly 
     s/^(\s+)/.\/$1/; 
     s/^/< /; 
     $_.qq/\0/; 
    } @ARGV; 
} 
1; 

Aby wymusić użycie tego pakietu w całym systemie, można użyć aliasu jako Patrick J.S.Sugeruje

alias perl='perl -MSanitize::ARGV' 

lub ustawić dla całego systemu PERL5OPT zmienną

PERL5OPT="-MSanitize::ARGV" 

A jeśli chcesz być bardziej paranoidalny, ukryć swoją Perl systemową (zmień jego nazwę na coś niezrozumiale) i zastąpić go z obwolutą

#!/bin/bash 
THE_REAL_PERL=/usr/bin/glorbqweroinuerqwer 
$THE_REAL_PERL -MSanitize::ARGV "[email protected]" 

owijka powłoka nadal pod uwagę wszelkie własne modyfikacje PERL5OPT


W ogólnym przypadku można użyć mechanizmu CORE::GLOBAL, aby zastąpić wbudowaną funkcję open, np.

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; 

i gdy moduł jest w użyciu będzie można złapać kogoś w akcie przy użyciu 2-Arg open połączenia. Niestety, myślę, że mechanizm magii uchwytów plików omija go, więc nadal nie pomaga w przypadku głupich nazw plików w wierszu poleceń w jednolinijkowym.

+0

Tak, znam sposoby sprawdzania poprawności "@ ARGV". Moje pytanie brzmi: czy mimo to zmusić "perl" do otwarcia trzech argumentów? – cuonglm

+0

Możesz ustawić podklucz 'CORE :: GLOBAL :: open' (i spróbowałem go sprawdzić, czy to rozwiąże twój problem), ale myślę, że magia mechanizmu ARGV omija go. – mob

+0

Cóż, o tym wspomniałem w moim pytaniu. I domyślam się, że konfiguracja 'CORE :: GLOBAL :: open' nie przynosi efektów. Od kiedy przełącznik '-n' i' -p' wyzwala operatora diamentowego '<>', który używa dwóch argumentów postaci 'otwartej'. – cuonglm

Powiązane problemy