Czy jest jakiś powód, aby nie przechodzić bezpośrednio z kodu JavaScript po stronie klienta do bazy danych?

62

Możliwa duplikat:
pisanie internetowych aplikacji „bez serwera”

Powiedzmy, że zbuduję klon Stack Exchange i zdecyduję się użyć czegoś takiego jak CouchDB jako mojego sklepu z zapleczem. Jeśli korzystam z wbudowanego uwierzytelniania i autoryzacji na poziomie bazy danych, to czy jest jakiś powód, aby nie pozwalać skryptowi JavaScript po stronie klienta pisać bezpośrednio na publicznie dostępnym serwerze CouchDB? Ponieważ jest to w zasadzie aplikacja CRUD, a logika biznesowa polega na tym, że „tylko autor może edytować swój post”, nie widzę potrzeby posiadania warstwy między elementami po stronie klienta a bazą danych. Po prostu użyłbym sprawdzania poprawności po stronie CouchDB, aby upewnić się, że ktoś nie wprowadza śmieciowych danych i upewnić się, że uprawnienia są ustawione poprawnie, aby użytkownicy mogli czytać tylko własne dane użytkownika. Renderowanie byłoby wykonywane po stronie klienta przez coś takiego jak AngularJS. W gruncie rzeczy możesz mieć serwer CouchDB i kilka „statycznych” stron i możesz zacząć. Nie potrzebujesz żadnego przetwarzania po stronie serwera, tylko coś, co mogłoby obsłużyć strony HTML.

Otwarcie mojej bazy danych na świat wydaje się niewłaściwe, ale w tym scenariuszu nie mogę wymyślić, dlaczego, dopóki uprawnienia są ustawione poprawnie. Jest to sprzeczne z moim instynktem jako programisty stron internetowych, ale nie mam dobrego powodu. Dlaczego to zły pomysł?

EDYCJA: Wygląda na to, że jest tutaj podobna dyskusja: Pisanie aplikacji internetowych „bez serwera”

EDYCJA: Jak dotąd niesamowita dyskusja i doceniam opinie wszystkich! Wydaje mi się, że powinienem dodać kilka ogólnych założeń zamiast wzywać CouchDB i AngularJS. Załóżmy więc, że:

  • Baza danych może uwierzytelniać użytkowników bezpośrednio z ukrytego sklepu
  • Cała komunikacja z bazą danych odbywa się za pośrednictwem protokołu SSL
  • Sprawdzanie poprawności danych może (ale może nie powinno?) Być obsługiwane przez bazę danych
  • Jedyną autoryzacją, na której nam zależy, poza funkcjami administracyjnymi, jest możliwość edytowania własnego postu
  • Nie ma problemu, że każdy może odczytać wszystkie dane (Z WYJĄTKIEM rekordów użytkowników, które mogą zawierać skróty haseł)
  • Funkcje administracyjne byłyby ograniczone przez autoryzację bazy danych
  • Nikt nie może dodać się do roli administratora
  • Baza danych jest stosunkowo łatwa do skalowania
  • Prawdziwa logika biznesowa jest niewielka lub żadna; jest to podstawowa aplikacja CRUD
Chris Smith
źródło
Niezupełnie czysta „strona klienta do bazy danych”, ale czy spojrzałeś na Parse i Firebase? (a także Meteor do pewnego poziomu), wszystkie mają dość trafne koncepcje i wszystkie traktują bezpieczeństwo w kreatywny sposób. np. zobacz to: blog.firebase.com/post/38234264120/...
Eran Medan,
Tak! Słyszałem o Parse wcześniej, ale nie Firebase. Bardzo interesujące i zdecydowanie zgodne z tym, o czym myślałem.
Chris Smith
Jak twoja baza danych chroni przed iniekcją SQL lub wysyłaniem XSS z JavaScript? Prawie wszystko, co klient wysyła, musisz założyć, że jest niebezpieczne, więc jakie są zapisy w tej bazie danych, których możesz użyć do filtrowania danych, aby upewnić się, że są prawidłowe i wstawić dane z przygotowanymi instrukcjami?
zuallauz,
6
Ignorując wszystko inne, tworzysz aplikację 2-poziomową, która ściśle łączy interfejs użytkownika z bazą danych. Niezbyt dobry pomysł, chyba że twoja aplikacja jest trywialna.
Andy
12
SSL nie zatrzyma kogoś uruchomionegoDELETE FROM ImportantData;
user253751

Odpowiedzi:

48

Postępowanie zgodnie z sugestią tworzy ścisłe połączenie między językiem po stronie klienta a bazą danych.

To może być w porządku - jest mniej kodu do napisania i utrzymania, a teoretycznie debugowanie może / powinno pójść trochę szybciej.

Z drugiej strony utrudnia to inne aspekty. Jeśli / kiedy będziesz musiał zmienić którąś z tych technologii, będziesz miał trudniejszy czas z powodu ciasnego połączenia między nimi.

Zabezpieczenie się przed atakami będzie (dość) nieco trudniejsze. Zakładasz, że klient zawsze będzie prezentował ładnie sformatowane żądania w bazie danych. Zakłada się, że nikt nigdy nie zhakuje kodu po stronie klienta, aby wstawić złośliwe instrukcje. Innymi słowy, „pożyczą” one twoje mechanizmy uwierzytelnienia i zastąpią normalny kod klienta swoim.

Nie poleciłbym tego, a wielu stanowczo powiedziałoby ci, żebyś tego nie robił. Ale można to zrobić.


źródło
Ciekawy. W jaki sposób osoba atakująca może pożyczyć mój mechanizm uwierzytelniania? Nie ufałbym klientowi w zakresie uwierzytelnienia. Baza danych po prostu zabrałaby HTTPS POST do punktu końcowego sesji, który haszuje hasło POSTed i sprawdza, czy jest poprawne. Jeśli tak, zwróci plik cookie sesji do wykorzystania w przyszłych żądaniach.
Chris Smith
1
Potrzebuję tylko pliku cookie sesji, prawda? Używam twojego klienta do uwierzytelnienia i pobrania mojego pliku cookie sesji. Następnie kradnę cookie sesji z moim klientem i wysyłam źle sformatowane żądania, które powodują spustoszenie. Pamiętaj, że wszystko jest na mojej maszynie, więc nawet nie potrzebuję ataku MiTM.
7
@ChrisSmith - tak długo, jak czujesz, że zajmujesz się kwestiami bezpieczeństwa, zajmujesz się głównym sprzeciwem wobec tego, co sugerujesz. Jeśli masz je załatwione lub uważasz, że tak, to idź do niego. Prosta wersja twojego pytania brzmi: zapytałeś, dlaczego ludzie nie robią ABC. Podstawową odpowiedzią jest bezpieczeństwo i ścisłe połączenie. Rozwiąż te obawy i usuń kod.
2
Nie wspominając o tym, że nie masz miejsca na buforowanie często żądanych danych, więc musisz za każdym razem uderzać w DB. Jasne, może twój sterownik DB ma trochę buforowania, ale jak to jest przestrajalne? Czy będzie udostępniany między wątkami?
TMN,
1
Czuję się niekomfortowo zezwalając na bezpośredni dostęp do moich baz danych SQL za pośrednictwem bezpośrednich instrukcji SQL z klientów WWW, ponieważ nigdy nie wiadomo, jakie będą żądania. Czy będą uruchamiać instrukcje usuwania, aktualizacji lub wstawiania? Jeśli tak, to czy dostarczą dane, których oczekuje Twoja aplikacja? Czy nastąpi nieoczekiwane usunięcie? Nieoczekiwane zmiany w bazie danych zwykle powodują uszkodzenie aplikacji. Najlepiej jest zminimalizować liczbę poleceń przesyłanych do bazy danych, aby łatwiej było odkażać otrzymywane dane wejściowe, aby aplikacja miała większe szanse na prawidłowe działanie.
Nathan Pilling,
36

To chyba nie jest świetny pomysł. Pierwszym i najsilniejszym powodem, jaki mogę podać, jest to, że serwer bazy danych nie jest zaprojektowany jako publiczny serwer WWW. Przeciwnie, konwencjonalna mądrość mówi, że powinieneś ukryć swoją bazę danych za zaporą ogniową.

Jeśli potrzebujesz dowodów potwierdzających, istnieje wiele obaw - nie wszystkie nie do pokonania, ale wiele do przemyślenia. W żadnej konkretnej kolejności, oto kilka:

  • Nie może przeprowadzić czyszczenia zapytań, ponieważ wysyłasz je bezpośrednio.
  • Uprawnienia do bazy danych zwykle działają inaczej niż uprawnienia do serwera WWW i aplikacji. Serwery sieci Web i struktury aplikacji zaczynają od niczego, a Ty musisz jawnie tworzyć i ujawniać poszczególne zasoby, punkty końcowe i działania. Z drugiej strony bazy danych proszą o przyznanie ról na wysokim poziomie.
  • Prawdopodobnie nie jest dobrze zoptymalizowany, aby utrzymać obciążenie serwera WWW; nie możesz korzystać z puli połączeń.
  • Bardziej popularne serwery WWW zostały podzielone na wiele . I otrzymali wiele poprawek bezpieczeństwa. Twój system DBMS został zasadniczo zaprojektowany do ukrywania się za zaporą ogniową, więc prawdopodobnie nie został przetestowany nawet przez ułamek procent potencjalnych zagrożeń, z którymi będzie miał do czynienia w publicznej sieci.
  • Państwo musi używać języka zapytań do bazy danych w celu ochrony prywatnych danych. W zależności od systemu DBMS może to być trudne.
  • Państwo musi używać języka zapytań do bazy danych, aby filtrować dużych zestawów danych - coś może dążyć do i tak; ale coś, co może stać się uciążliwe dla bardziej skomplikowanych reguł biznesowych.
  • Ograniczone lub brak wsparcia dla bibliotek stron trzecich.
  • Bardzo ograniczone (potencjalnie zerowe) wsparcie społeczności dla wielu napotkanych problemów.

... I jestem pewien, że istnieją inne obawy. I jestem pewien, że istnieje rozwiązanie większości - jeśli nie wszystkich z tych obaw. Ale jest lista na początek!

svidgen
źródło
1
Świetne jedzenie do przemyślenia tutaj. Nie wszystkie z tych punktów będą miały zastosowanie w każdej sytuacji i będą równie ważne, ale świetnie jest mieć zwięzłą listę punktów, która dostarczy sprzęt. Dzięki!
Dav
16

Najlepszy pojedynczy powód, jaki mogę sobie wyobrazić, to: ponieważ ta metoda nie jest bezpośrednio obsługiwana ani zalecana przez żadną z zaangażowanych stron.

Dostawcy przeglądarek, standardy EcmaScript, programiści systemów baz danych, producenci sprzętu sieciowego, architekci hostingu / infrastruktury oraz specjaliści ds. Bezpieczeństwa nie obsługują (a nawet nie rozważają) proponowanego przypadku użycia. Jest to problem, ponieważ proponowana metoda wymaga, aby wszystkie te podmioty - i więcej - działały poprawnie dla Twojej aplikacji, nawet jeśli żaden z zaangażowanych systemów nie został zaprojektowany do obsługi tego.

Nie mówię, że to niemożliwe. Mówię tylko, że to mniej przypomina „ponowne wynalezienie koła”, a bardziej ponowne wynalezienie opartej na przeglądarce interakcji klient-serwer.

W najlepszym razie wykonasz mnóstwo pracy, aby nawet systemy działały na możliwie najbardziej podstawowym poziomie. Współczesne popularne bazy danych nie są RESTful'owe ani zbudowane do pracy przez HTTP, więc będziesz budował swoje własne (oparte na WebSocket) sterowniki klienta.

Nawet jeśli wszystko sprawdzi się technicznie, zrezygnujesz z wielu najpotężniejszych funkcji współczesnej architektury. Nie będziesz mieć dogłębnej obrony - każdy może łatwo połączyć się bezpośrednio z głównym celem większości prób włamań do witryny. Ale proponowany przez ciebie scenariusz jest znacznie gorszy.

Proponowany model nie tylko ujawnia serwer - ujawnia prawidłowe parametry połączenia. Atakujący nie mogą po prostu pingować serwera - mogą aktywnie się logować i podawać polecenia. Nawet jeśli możesz ograniczyć dostęp do danych, nie jestem świadomy wystarczającego oprzyrządowania w systemach DBMS do ochrony przed scenariuszami Denial of Service i ich podobnymi. Podczas pracy w ulepszonych wersjach SQL, takich jak TSQL, często niezwykle łatwo jest produkować bomby, które działają skutecznie nieskończenie długo (kilka nieograniczonych połączeń, aby stworzyć produkt kartezjański, a będziesz mieć WYBÓR, który będzie działał na zawsze, wykonując ciężką pracę) . Wyobrażam sobie, że musisz wyłączyć większość funkcji SQL, a nawet wyeliminować podstawowe zapytania SELECT za pomocą JOIN i być może zezwolić tylko na wywoływanie procedur przechowywanych? Nawet nie wiem, czy możesz to zrobić, nigdy nie zostałem poproszony o próbę. Nie robi

Skalowalność bazy danych jest również jednym z najtrudniejszych problemów w pracy na dużą skalę, podczas gdy skalowanie wielu serwerów HTTP - szczególnie ze stronami statycznymi lub buforowanymi - jest jedną z najłatwiejszych części. Twoja propozycja sprawia, że ​​baza danych wykonuje więcej pracy, ponosząc odpowiedzialność w zasadzie za 100% aktywności po stronie serwera. To wada mordercza sama w sobie. Korzyści z przeniesienia pracy na klienta tracisz, przenosząc więcej pracy do bazy danych.

Na koniec chciałbym tylko podkreślić, że sedno tego, co proponujecie, nie jest nowe, ale faktycznie sięga dziesięcioleci. Model ten nazywany jest modelem „grubej bazy danych”, który zasadniczo przeniósł większość logiki po stronie serwera do bazy danych, tak jak proponujesz. Istnieje wiele powodów, dla których model ten przeszedł na masową skalę w Internecie, i prawdopodobnie warto byłoby przyjrzeć się bliżej tej historii. Zauważ też, że nawet wtedy niewiele było rozważań, aby całkowicie niezaufani użytkownicy mogli zalogować się do systemu i uruchamiać polecenia, ponieważ dostęp byłby nadal kontrolowany w celu wybrania wewnętrznych (znanych) użytkowników, którzy nie powinni stale atakować systemu.

Faktem jest, że nadal potrzebujesz serwera HTTP do obsługi plików, ponieważ systemy baz danych po prostu tego nie robią. Jednocześnie wszystko, co proponujesz, można uzyskać za pomocą cienkiego modelu serwera (takiego jak Nodejs) w celu udostępnienia interfejsu RESTful w bazie danych. Jest to popularne z jakiegoś powodu - działa, utrzymuje bazę danych w ukryciu za warstwami ochrony, jest niezwykle skalowalne, a jednak pozwala budować bazę danych tak grubą lub cienką, jak chcesz.

BrianH
źródło
8

Ponieważ jest to w zasadzie aplikacja CRUD, a logika biznesowa polega na tym, że „tylko autor może edytować swój post”, nie widzę potrzeby tworzenia warstwy między aplikacjami po stronie klienta a bazą danych. Po prostu użyłbym sprawdzania poprawności po stronie CouchDB, aby upewnić się, że ktoś nie wprowadza danych śmieci i upewnić się, że uprawnienia są ustawione poprawnie, aby użytkownicy mogli tylko czytać własne dane użytkownika.

Cóż, przeniesienie autoryzacji (kwestie bezpieczeństwa) i walidacja logiki z dala od bazy danych zapewnia rozdzielenie problemów w systemie oprogramowania. W ten sposób można testować, konserwować, skalować i ponownie wykorzystywać logiczne bloki kodu przy mniejszym ryzyku hamowania funkcji w systemie.

Zapewnienie możliwości bezpośredniego wprowadzania danych przez klienta do bazy danych ma bardzo duży potencjał do zepsucia danych .

Oznacza to również, że unikanie / usuwanie ciasnego połączenia sprawia, że ​​system oprogramowania jest łatwiejszy w utrzymaniu i SOLIDNY.

EL Yusubov
źródło
1
Zwykle się z tym zgadzam, ale mogę testować, utrzymywać i skalować bloki kodu w kodzie klienta tak łatwo, jak po stronie serwera. Robienie tego wszystkiego w Javascripcie nie byłoby usprawiedliwieniem, aby nie stosować właściwego rozdzielenia problemów. Po prostu przenoszę rzeczywiste przetwarzanie z serwera do klienta. Więc jaka jest granica między kupowaniem mnie?
Chris Smith
2
Sprawdzanie poprawności po stronie klienta jest przyjemne dla klienta, ale posiadanie go po stronie serwera jest bardziej krytyczne niż kiedykolwiek. Ponieważ żądanie po stronie klienta można łatwo zasymulować. Posiadanie logicznych separacji i / lub poziomów pomaga w towarzyskości i utrzymaniu.
EL Yusubov,
Tak więc, grając w adwokata diabła: Jak wspomniałem poniżej, mogłem użyć funkcji sprawdzania poprawności CouchDB, aby ustalić, czy przesyłane dane są prawidłowe. Za każdym razem, gdy próbujesz dodać lub zaktualizować dokument, sprawdzi on, czy masz pozwolenie i czy jest on poprawnie sformatowany. Nakłada to więcej przetwarzania po stronie bazy danych, ale jest dość lekki i i tak muszę rozważyć skalowanie strony danych. Czy to nie rozwiąże problemu?
Chris Smith
Nie, nie sądzę. Umieszczenie logiki sprawdzania poprawności i autoryzacji w DB będzie miało negatywny wpływ na wydajność w twoim systemie, gdy liczba rekordów zacznie rosnąć i zyskasz więcej użytkowników w systemie.
EL Yusubov,
Silniki DB służą do przechowywania i pobierania danych, a nie do manipulowania nimi ani sprawdzania ich poprawności. Oczywiście możesz to zrobić po swojemu, ale nie jest to skuteczny sposób na naśladowanie.
EL Yusubov,
6

Umożliwienie użytkownikowi bezpośredniej interakcji z bazą danych wydaje mi się naprawdę niebezpieczne.

Czy mechanizm uwierzytelniania w CouchDB jest tak wyrafinowany, że można odizolować dostęp do odczytu i zapisu użytkownika tylko do danych, które ma on czytać i zapisywać (mówimy o dostępie do dokumentu, a może nawet do pola dokumentu) uprawnienia tutaj)? Co z danymi „wspólnymi”, które są udostępniane przez wielu użytkowników? Czy w ogóle nie ma tego w twoim projekcie aplikacji?

Czy naprawdę chcesz, aby użytkownik mógł W KAŻDY sposób zmieniać swoje dane? Co na przykład z zastrzykami XSS? Czy nie byłoby lepiej mieć warstwę serwera do filtrowania ich, zanim wejdą do bazy danych?

Philipp
źródło
1
Przywołujesz dobre punkty, a ja myślałem o tym samym. Doszedłem do wniosku, że w tej (hipotetycznej) aplikacji nie mam nic przeciwko czytaniu czegokolwiek Z WYJĄTKIEM rekordów użytkownika. Mogą pisać tylko do dokumentów, które pierwotnie utworzyli (co jest jedyną „logiką biznesową”, o której wspomniałem powyżej). Wygląda na to, że CouchDB ma możliwość robienia obu tych rzeczy za pośrednictwem wewnętrznej bazy danych _users i funkcji sprawdzania poprawności.
Chris Smith
6

Masz wiele powodów, ale jest jeszcze jeden: zabezpieczenie na przyszłość. Wcześniej czy później, w miarę ewolucji aplikacji, pojawi się pewne wymaganie, którego nie można łatwo lub bezpiecznie osiągnąć w JS po stronie klienta lub jako procedurę przechowywaną w bazie danych.

Na przykład powiedziano ci, że wszystkie nowe rejestracje muszą mieć weryfikację CAPTCHA, aby były ważne. Byłoby to naprawdę łatwe z praktycznie każdym nowoczesnym środowiskiem aplikacji internetowych. Wystarczy uderzyć reCAPTCHA w formularzu rejestracyjnym, przekazać token odpowiedzi reCAPTCHA z powrotem do backendu i dodać kilka linii kodu do backendu, aby zweryfikować ważność tokena za pomocą API Google (lub jeszcze lepiej, użyj biblioteki, którą ktoś inny napisał, aby to zrobić dla Was).

Jeśli używasz systemu dwupoziomowego i polegasz na bazie danych dla całej logiki po stronie serwera, jak zamierzasz zweryfikować token? Tak, przypuszczam, że teoretycznie jest możliwe, w zależności od DBMS, napisanie procedury składowanej, która w jakiś sposób wywołuje powłokę i wywołuje curl z odpowiednimi argumentami. To prawie na pewno okropny pomysł: filtrowanie danych wejściowych i ochrona przed lukami w zabezpieczeniach byłyby straszne; miałbyś bałagan związany z obsługą błędów i przekroczeniami czasu; i musiałbyś sam przeanalizować odpowiedź. Nie wspominając już o tym, że DBMS nie jest przeznaczony do tego, więc nie ma powodu, aby sądzić, że wydajność, stabilność, bezpieczeństwo wątków itp. Nie będą problemami. Zobacz na przykład ten wątek , który omawia niektóre z tych problemów dotyczących Postgres.

I to tylko problemy związane z dodawaniem jednego prostego CAPTCHA do formularza. Co zamierzasz zrobić, jeśli chcesz dodać weryfikację SMS lub zadanie w tle, w którym nieaktywni użytkownicy wysyłają e-maile do nieaktywnych użytkowników, aby przypominać im o Twojej aplikacji, lub dodają funkcję przesyłania plików, aby ludzie mogli ustawić zdjęcie profilowe? Może zdecydujesz, że Twoja aplikacja będzie miała kiedyś zautomatyzowane testy? A może chcesz śledzić zmiany w procedurach w systemie kontroli wersji? Istnieje wiele bibliotek i narzędzi dla większości użytecznych języków do obsługi większości tych zadań, ale niewiele lub wcale nie będzie dostępnych dla Twojego DBMS, ponieważ nie jest to przeznaczone.

W końcu będziesz chciał zrobić coś, czego nie można racjonalnie zrobić bezpośrednio w DBMS, a następnie utkniesz. Ponieważ zbudujesz całą aplikację w DBMS, nie będziesz miał innego wyjścia, jak tylko zdobyć serwer WWW i rozpocząć odbudowę elementów w innym języku, aby dodać prostą funkcję.

To byłby prawdziwy wstyd, ponieważ mamy już nazwę miejsca, w którym umieszczasz logikę aplikacji, i to z jakiegoś powodu nazywa się to „kodem źródłowym aplikacji”, a nie „procedurami przechowywanymi w bazie danych”.

Zach Lipton
źródło
5

Jeśli kontrole bezpieczeństwa i logika biznesowa są zawarte w javascript po stronie klienta, mogą zostać zastąpione przez złośliwego użytkownika. Alternatywnie możesz wykorzystać technologię po stronie serwera opartą na JavaScript (np. Node.JS ) do obsługi sprawdzania poprawności, autoryzacji i tym podobnych.

Michael Brown
źródło
Uwierzytelnianie i autoryzacja byłyby obsługiwane przez samą bazę danych, więc nie ufałbym klientowi w tym względzie. CouchDB ma wbudowane funkcje sprawdzania poprawności, które uruchamiają się przy każdej próbie aktualizacji dokumentu, więc użyłbym ich do sprawdzenia, czy przesyłane informacje są prawidłowe.
Chris Smith
2

Wszelkie ograniczenia biznesowe, które możesz chcieć zapewnić, powinny zostać zweryfikowane po stronie serwera. Nawet jeśli kontrolujesz dostęp użytkownika, ktoś może wysłać nieprawidłowe dane.

Zgodnie z przykładem klonowania przepływu stosu:

  • W jaki sposób zablokowałbyś edytowanie „zamkniętych” pytań na stronie?
  • Jak zapobiegniesz usuwaniu komentarzy przez osoby?
  • Jak zapobiegniesz fałszowaniu dat komentarzy?
  • W jaki sposób miałbyś powstrzymać ludzi przed 50-krotnym aktualizowaniem tego samego postu?
  • Prawdopodobnie jest o wiele więcej przykładów, jeśli kopiesz trochę więcej.

Każdy może manipulować kodem po stronie klienta i całkowicie naruszać integralność danych (nawet jeśli jest ograniczony do niektórych obiektów, takich jak ich własne posty).

Jbm
źródło
1

Edytuj stronę w Firebug i w pewnym momencie wstaw linię podobną do tej:

ExecDbCommand("DROP TABLE Users")

Uruchom.

Edytować:

Pytanie było w rzeczywistości o CounchDB, więc nie ma tu sql do uruchomienia. Ale pomysł jest taki sam. Zakładam, że każda nietrywialna aplikacja zależy od danych w celu przestrzegania niektórych reguł spójności, które są sprawdzane / egzekwowane przez kod aplikacji. Złośliwy użytkownik może zmodyfikować kod klienta, aby zapisać dane w formie, która narusza reguły biznesowe i może spowodować spustoszenie w aplikacji.

Jeśli witryna uwzględnia wszystkie możliwe stany danych, które będą ważne z perspektywy biznesu następnie przez wszystkich środków pójść tą drogą, ale jeśli to nie jest przypadek (prawdopodobne), to chciałby mieć gwarancję, że wszelkie dane, które dostaje przechowywane są generowane przez TWOJEJ kod i zgodnie z twoimi zasadami .

AZ01
źródło
CouchDB nie wiedziałby, co z tym zrobić, ale rozumiem o co ci chodzi. Jeśli uprawnienia są ustawione poprawnie, odpowiedzią na takie działanie byłoby 401 Nieautoryzowane.
Chris Smith
-1, kiedy publikujesz kod SQL, oczywiście nie wiesz nawet, co to jest CouchDB. Ponadto, tworząc konto administratora na CouchDB, już uniemożliwiasz innym użytkownikom wykonywanie najbardziej niebezpiecznych operacji.
Filipiny,
Słusznie. w pytaniu pominąłem część na CouchDB i zarejestrowałem ją tylko jako „dostęp do magazynu danych bezpośrednio po stronie klienta JS”. Zmienię odpowiedź.
AZ01,
1
+1, SQL czy nie, jego punkt nadal obowiązuje. Za pomocą debugera JS można zmienić sposób uzyskiwania dostępu do danych.
GrandmasterB,
1

Wiem, że to stare pytanie, ale chciałem się do niego odezwać, ponieważ moje doświadczenie różni się od innych odpowiedzi.

Spędziłem wiele lat pisząc aplikacje współpracujące w czasie rzeczywistym. Ogólnym podejściem do tych aplikacji jest lokalna replikacja danych i możliwie najszybsza synchronizacja zmian z urządzeniami równorzędnymi. Wszystkie operacje na danych są lokalne, więc przechowywanie danych, dostęp do danych, logika biznesowa i interfejs użytkownika są warstwami lokalnymi. Ruch „najpierw offline” ( http://offlinefirst.org/ ) przyjął to podejście do tworzenia aplikacji internetowych offline i może mieć pewne odpowiednie zasoby. Tego rodzaju przypadki użycia wymagają nie tylko otwarcia warstwy dostępu do danych dla klientów, ale także przechowywania danych! Wiem wiem. Wydaje się szalony, prawda?

Obawy dotyczące takich aplikacji offline są podobne do tych, o które prosiłeś, tylko jeden poziom został usunięty. Wydaje mi się to istotne. Biorąc pod uwagę, że otwierasz bezpośredni dostęp do danych dla klientów, pojawia się pytanie, w jaki sposób możesz ograniczyć skutki działania złośliwego użytkownika? Cóż, istnieje wiele strategii, ale nie są one oczywiste, jeśli pochodzisz z bardziej tradycyjnego środowiska programistycznego.

Pierwszym nieporozumieniem jest to, że ujawnienie bazy danych oznacza ujawnienie wszystkich danych. Weźmy na przykład CouchDB; bazy danych w CouchDB są lekkie, więc nie pomyślałbyś o stworzeniu setek tysięcy oddzielnych baz danych na serwerze. Użytkownicy mogą uzyskiwać dostęp tylko do baz danych, do których mają uprawnienia dostępu jako czytelnik lub pisarz (nie mówiąc już o funkcjach sprawdzania poprawności i innych funkcjach CouchDB), dzięki czemu mogą uzyskać dostęp tylko do podzbioru danych.

Drugie nieporozumienie polega na tym, że problem z crapsowaniem danych przez użytkownika! Jeśli użytkownicy otrzymają replikę bazy danych, mogą na niej zgarnąć wszystko, co lubią, bez wpływu na innych użytkowników. Ale powinieneś zweryfikować ich zmiany przed replikacją ich danych z powrotem do „centralnego” sklepu. Pomyśl o Git - użytkownicy mogą robić, co im się podoba, w oddziałach, rozwidleniach i lokalnych repozytoriach bez wpływu na gałąź główną. Połączenie z powrotem do mistrza wymaga dużo ceremonii i nie odbywa się na ślepo.

Buduję system obecnie korzystający z CouchDB, w którym użytkownicy muszą współpracować przy danych, aby zbudować zestaw danych, który jest następnie „publikowany” za pośrednictwem przepływu pracy QA / QC. Współpraca odbywa się na replice danych (nazywamy to tymczasową lub działającą bazą danych), a po zakończeniu osoba odpowiedzialna przeprowadza kontrolę jakości danych i dopiero po tym jest replikowana z powrotem do głównego repozytorium.

Wynika z tego wiele korzyści, które są trudne do osiągnięcia w innych systemach - jak kontrola wersji, replikacja i współpraca (niech działa offline!) Dla tradycyjnych trzypoziomowych aplikacji CRUD jest bardzo trudna.

Moja rada - jeśli Twoja aplikacja jest „tradycyjna”, zrób to w tradycyjny sposób. Jeśli którakolwiek z wyżej wymienionych rzeczy (choć jest o wiele więcej ...) dotyczy Ciebie, rozważ alternatywną architekturę i przygotuj się na późniejsze przemyślenia.

Daniel Paull
źródło
0

Myślę, że biorąc pod uwagę wszystkie twoje założenia, możliwe jest przejście bezpośrednio od klienta do bazy danych. Jednak uzasadnione jest sprawdzenie, czy twoje założenia są prawidłowe i prawdopodobnie tak pozostaną w przyszłości.

Martwiłbym się, że w przyszłości odczytanie wszystkich danych może nie być w porządku, a zwłaszcza, że ​​w przyszłości może rozwinąć większą logikę biznesową. Oba są bardziej prawdopodobne, jeśli projekt zakończy się sukcesem.

Tak długo, jak dasz sobie radę z tymi problemami w przyszłości, i jeśli rzeczywiście będziesz musiał je rozwiązać, myślę, że twój projekt będzie działał. Myślę, że będziesz musiał bardzo uważać, aby rozdzielić obawy w kodzie JavaScript, a niektóre z nich mogą później zostać przepisane na serwerze.

Ale zdecydowanie mogłem zobaczyć, gdzie warto ryzykować, że zrobię to później, a korzyści wynikające z mniejszej liczby części ruchomych dzisiaj.

psr
źródło
Słuszna uwaga. Jest to zdecydowanie wąski przypadek użycia, więc nie można go zastosować do żadnej aplikacji.
Chris Smith
0

Przede wszystkim dziękuję za pytanie OUT OF THE BOX .... :)

Ale sugerowałbym to; Zawsze staraj się zachować segregację między 3 warstwami. które to Prezentacja / Biznes i Baza danych lub DAO, ponieważ będzie to najlepsza praktyka w tego rodzaju wymaganiach i konfiguracjach, w których każdego dnia będzie wiele zmian.

W prostych światach twoja warstwa prezentacji nie powinna wiedzieć o warstwie bazy danych, tzn. Format niektórych pól typu daty może różnić się od warstwy prezentacji i warstwy bazy danych, aby użytkownik miał swobodę wyboru odpowiedniego formatu daty zgodnie z własnymi potrzebami.

A Business Logic musi działać jak połączenie warstwy prezentacji z warstwą bazy danych / Dao, jak rzutowanie pól, niektóre walidacje biznesowe itp. Powinny być obsługiwane w warstwie biznesowej, a nie w sekcji Javascript, zgodnie z pytaniem.

Ta segregacja zapewni Ci dużą łatwość i wygodę podczas złożonych scenariuszy, funkcji, a nawet złożonych weryfikacji. Największą zaletą jest to, że możesz mieć różne technologie do wdrażania tych warstw i można je zmieniać zgodnie z potrzebami lub zakresem działalności.

Dzięki

Logicalj
źródło
0

Jeśli chcesz zbudować SQL w JavaScript i wysłać go do bazy danych, która weryfikuje prawa itp., Niż ze względów bezpieczeństwa byłaby to katastrofa. Po prostu dlatego, że kiedy budujesz API i sam tworzysz zapytania, musisz analizować z punktu widzenia bezpieczeństwa tylko ograniczoną liczbę zapytań. Jeśli zapytania są budowane poza systemem, masz potencjalnie nieograniczoną liczbę sztuczek, które ktoś może zrobić.

Ale tak nie jest, ponieważ korzystasz z bazy danych klucz-wartość (tak jak rozumiem, CouchDB ogólnie należy do tej kategorii). Sam interfejs bazy danych jest rodzajem warstwy środkowej i jest testowany ze względów bezpieczeństwa przez zespół Apache. Ze względu na stosunkowo prosty JavaScript API jest to jeszcze łatwiejsze do analizy pod kątem potencjalnych wad niż tak skomplikowane interfejsy, jakie mają aplikacje JSF.

Może to być bezpieczne rozwiązanie, jeśli wykonujesz złożone testy bezpieczeństwa. Może to być jeszcze łatwiejsze, niż w przypadku korzystania z frameworków takich jak JSF, które często używają za sobą mało czytelnego API. Bezpieczeństwo przez zaciemnienie nie jest uważane za rozwiązanie.

W odniesieniu do twojego pytania i tak nie będzie to bezpośredni dostęp do bazy danych. Bezpośrednim dostępem byłoby budowanie zapytań SQL w JavaScript (niestety, widziałem takie rozwiązania). W twoim przypadku sama CouchDB stanowi warstwę izolacyjną. Możesz oczywiście owinąć go w API, aby go wzmocnić, ale tak długo, jak możesz łatwo przetestować, co może zrobić konkretny użytkownik, i jeśli ograniczenia bezpieczeństwa działają dla Ciebie, będziesz mieć bezpieczne i solidne rozwiązanie bez dodatkowych warstw.

Żeglarz naddunajski
źródło
0

Widzę dwa problemy:

1. Tight Coupling: Zmienić opcję DB? Cóż, teraz musisz również zmienić cały kod po stronie klienta. Zaufaj mi. Nie potrzebujemy więcej problemów po stronie klienta.

2. Problem bezpieczeństwa TMI: zbyt wiele ujawnia, jak działają rzeczy. Auth może nadal stanowić przeszkodę, ale znalezienie exploita jest o wiele łatwiejsze, gdy dokładnie wiesz, co dzieje się po stronie serwera.

Bardzo, bardzo cienki poziom środkowy może być lepszym sposobem.

Erik Reppen
źródło
-1

Klient nie może korzystać z aplikacji internetowej, jeśli javascript jest wyłączony (lub nie jest obsługiwany w przeglądarce jego urządzenia), jeśli javascript jest jedyną warstwą dostępu do bazy danych.

k3b
źródło
2
Nie martwię się o to zbytnio. Większość stron internetowych i tak korzysta z Javascript. Być może będę musiał po prostu wydzielić tagi <noscript> i powiedzieć im, że muszą je włączyć, jeśli chcą, aby moja strona (i 80% innych tam) działała.
Chris Smith