2015-07-05 21 views
6

Pierwsze tło: mam kilka raczej prostych struktur danych, które są przechowywane jako pliki json na dysku. Te pliki json są udostępniane między aplikacjami różnych języków i różnych środowisk (takich jak frontend i narzędzia do manipulacji danymi).Czy parsowanie jsonów naiwnie w klasę lub strukturę Python jest bezpieczne?

Dla każdego z plików chcę utworzyć Python "POPO" (zwykły stary obiekt Pythona), a odpowiednia klasa mapera danych dla każdego elementu powinna implementować proste zachowanie podobne do CRUD (np. Zapisuje serializację klasy i magazynu jako plik json na dysku).

Myślę, że prosty program odwzorowujący (który zna tylko podstawowe typy) będzie działał. Jednak jestem zaniepokojony bezpieczeństwem. Niektóre pliki json będą generowane przez frontend sieciowy, więc możliwe zagrożenie bezpieczeństwa, jeśli użytkownik karmi mnie złym jsonem.

Wreszcie, oto prosty kod mapowania (znaleziono na How to convert JSON data into a Python object):

class User(object): 
def __init__(self, name, username): 
    self.name = name 
    self.username = username 

import json 
j = json.loads(your_json) 
u = User(**j) 

Co możliwe kwestie bezpieczeństwa widzisz?

NB: Jestem nowy w Pythonie.

Edytuj: Dziękuję wszystkim za komentarze. Dowiedziałem się, że mam jeden json, w którym mam 2 tablice, z których każda ma mapę. Niestety to zaczyna wyglądać jak staje się niewygodne, gdy mam ich więcej.

Rozszerzam pytanie, aby odwzorować wejście json na typ rekordu. Oryginalny kod pochodzi stąd: https://stackoverflow.com/a/15882054/1708349. Ponieważ muszę zmienny obiektów, chciałbym zmienić go używać namedlist zamiast namedtuple:

import json 
from namedlist import namedlist 

data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}' 

# Parse JSON into an object with attributes corresponding to dict keys. 
x = json.loads(data, object_hook=lambda d: namedlist('X', d.keys())(*d.values())) 
print x.name, x.hometown.name, x.hometown.id 

Czy to nadal jest bezpieczne?

+0

Jedyny problem jaki mogę sobie wyobrazić to to, że coś się zepsuje, ponieważ załadowano nieprawidłowe dane. – poke

+3

json może analizować tylko ograniczone typy, int, bool, itp. Nic nie zostanie wykonane, więc nie widzę żadnego prawdziwego zagrożenia bezpieczeństwa –

+0

Nadal będę sprawdzać poprawność danych wejściowych z usługi sieciowej, szczególnie jeśli te obiekty są trafi w bazę danych. Może coś takiego jak ograniczenie "nazwy" do 100 znaków drukowalnych i nie dopuszczanie jakiejś interpunkcji (jak średniki). Zobacz ten post http://stackoverflow.com/questions/421046/what-are-all-of-the-allowable-characters-for-peoples-names –

Odpowiedz

3

Nie można popełnić błędu w pierwszym przypadku. Ograniczasz, jakie argumenty można podać i łatwo jest dodać walidację/konwersję zaraz po załadowaniu z JSON.

Drugi przykład jest nieco gorszy. Pakowanie rzeczy w takie rekordy nie pomoże ci w żaden sposób. Nie dziedziczą żadnych metod, ponieważ każdy zdefiniowany przez ciebie typ jest nowy. Nie można łatwo porównywać wartości, ponieważ dyktury nie są uporządkowane. Nie wiesz, czy wszystkie argumenty zostały obsłużone, czy też istnieją dodatkowe dane, które później mogą prowadzić do ukrytych problemów.

Podsumowując: dzięki User(**data) jesteś całkiem bezpieczny. Dzięki namedlist jest miejsce na niejednoznaczność i naprawdę nic nie zyskujesz. (w porównaniu z gołym, parsowanym jsonem)

Powiązane problemy