2013-03-12 16 views
13

Pracuję nad aplikacją internetową, w której użytkownicy będą mogli dostarczać ciągi, które serwer następnie zastąpi zmiennymi.Czy ciąg napisów w formacie Python .format() może być bezpieczny dla niezaufanych ciągów formatów?

Najlepiej chciałbym użyć składni formatu PEP 3101() i zajmuję się możliwością nadpisania metod w Formatter, aby zapewnić bezpieczeństwo dla niezaufanych danych wejściowych.

Oto zagrożenia widzę z .format(), a to oznacza:

  • wyściółka pozwala na określenie dowolnych długościach, tak '{:> 9999999999}'. Format (..) mógłby uruchomić serwer z pamięci i być DOS. Musiałbym to wyłączyć.
  • Format pozwala uzyskać dostęp do pól wewnątrz obiektów, co jest przydatne, ale jest creepy, że można uzyskać dostęp do zmiennych dunder i rozpocząć wiercenia w bity standardowej biblioteki. Nie wiadomo, gdzie może być getattr(), który ma efekty uboczne lub zwraca coś tajnego. Dodałbym do białej listy dostęp do atrybutów/indeksu przez przesłonięcie funkcji get_field().
  • Oczywiście musiałabym złapać kilka wyjątków.

Moje założenia są następujące:

  • Żaden z tradycyjnym formacie C wyczynach smyczkowych dotyczą Pythona, ponieważ określając parametr to granice sprawdzony dostęp do kolekcji, zamiast bezpośrednio pstrykaliśmy stos wątku .
  • Używana przeze mnie struktura sieci ucieka przed każdą zmienną, która jest podstawiana w szablonie strony, i dopóki jest to ostatni przystanek przed wyjściem, jestem bezpieczny przed atakami typu cross-site scripting wyłaniającymi się z de-escaping.

Jakie są Twoje myśli? Możliwy? Niemożliwy? Tylko nierozsądne?


Edit: Armin Ronacher nakreśla paskudny wyciek informacji, jeśli nie odfiltrować Dunder dostęp do zmiennych, ale wydaje się uważać zabezpieczania format(), jak to wykonalne:

{local_foo.__init__.__globals__[secret_global]}

http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

(Osobiście nie przeszedłem do niezaufanego formatu format() w moim produkcie, ale aktualizuję je ze względu na kompletność)

+0

Brzmi nierozsądnie. Nie możesz po prostu użyć 'replace()'? – grc

+0

No cóż, dla funkcji start replace() wymaga podania hasła dla każdej zmiennej, która może znajdować się w łańcuchu, który skaluje się w sposób straszny. –

+0

Lemmie rozwija tę wizję, ponieważ przegapiłem moją szansę na jej edycję. Mój przypadek użycia to sytuacja podobna do MUD, w której zamierzam zrobić tonę formatowania ciągów z dużą ilością potencjalnych zmiennych. Mogłabym wrócić do słabszej formy formatowania ciągów takich jak 'string.Template', ale możliwość odwoływania się do pól wewnątrz obiektów jest również bardzo przydatna w moim przypadku. To jest coś, co mogę naśladować, budując mapę parametrów każdego pola z każdego argumentu w każdym wywołaniu, ale byłoby to uspokajające, gdybym miał coś lepszego. –

Odpowiedz

5

Dobry instynkt. Tak, osoba atakująca może dostarczyć dowolny ciąg formatu, jest luką pod pytonem.

  • Odmowa usługi jest prawdopodobnie najprostsza do rozwiązania. W tym przypadku ograniczenie tego ciągu lub liczby operatorów w ciągu zmniejszy ten problem. Powinno być ustawienie , w którym żaden rozsądny użytkownik nie będzie musiał generować ciągu znaków z więcej zmiennych niż X, a ta ilość obliczeń nie jest zagrożona z wykorzystania w ataku DoS.
  • Możliwość uzyskania dostępu do atrybutów w obiekcie może być niebezpieczna. Jednak nie uważam, że klasa nadrzędna Object ma jakiekolwiek przydatne informacje o .Obiekt dostarczony do formatu musiałby zawierać element wrażliwy. W każdym razie ten typ notacji może ograniczać z wyrażeniem regularnym .
  • Jeśli ciągi formatów są dostarczane przez użytkownika, użytkownik może potrzebować znać komunikat o błędzie podczas debugowania. Jednak komunikaty o błędach mogą zawierać informacje typu senstive, takie jak ścieżki lokalne lub nazwy klas. Ustaw , aby ograniczyć informacje, które może uzyskać osoba atakująca.

Przejrzyj python format string specification i zakazuj funkcji, których użytkownik nie chce używać z wyrażeniem regularnym.

+7

Albo jeszcze lepiej, * zezwól na * funkcjonalność, którą chcesz obsłużyć, więc gdy przejdziesz na nową wersję Pythona z nowymi (i potencjalnie niebezpiecznymi) opcjami formatu, nie zostaniesz złapany. – Michael

+0

@Michael tak, zgadzam się, że podejście do białej listy byłoby lepsze. – rook

Powiązane problemy