Czy warto zapisywać html oraz markdown w bazie danych, żeby później móc edytować komentarz.

0

Jest sobie system komentarzy na stronie internetowej. Użytkownik może edytować swoje komentarze. Do komentarzy używamy markdowna. Pytanie do osób, które pracowały nad czymś podobnym. Czy zapis markdowna oraz html do bazy danych to jest coś naturalnego? Generowanie html z markdowna odbywałoby się przy tworzeniu i edytowaniu. Pole typu string byłoby tylko potrzebne do uzupełnienia ekranu edytora komentarza.

Alternatywa jaką ja widzę to jakaś libka po stronie frontu, która zmienia html na markdown, ale widzę tu pewne problemy. Jestem ciekaw Waszego zdania na ten temat.

1

Ja to widzę tak:

  • user wpisuje komentarz, klika save czy jakikolwiek inny przycisk do zapisania komentarza,
  • Przycisk (button) ma podpięty eventAsser ripujący userInput jako string (bez SC) i wpisujący go do bazy

Edycja to po prostu podstawienie tekstu komentarza (o odpowiednim id) jako wartość pola tekstowego.

2

Robiłem coś takiego, mówię tutaj o zapisie HTML`a do bazy (komentarze userów) nie widzę w tym nic złego, jeśli to się robi z głową.
Przede wszystkim na backendzie przed jakimkolwiek zapisem musisz zwalidować tego htmla czy nie zawiera przypadkiem jakiś niechcianych rzeczy typu znaczników script itd.
Można ustawić whiteliste dozwolonych znaczników html i jeśli pojawi się jakiś nie dozwolony to nie zapisywać tego, są chyba gotowe libki do tego.

1

Jest to jak najbardziej dobra i powszechna praktyka. Niestety problem lezy gdzie indziej. Na początek, kto to może załadować? Jeżeli to jest autoryzowana, pewna osoba to jest OK. Jeżeli jest to random z internetu to na 100% znajdzie się taki, który doda złośliwy kod. Dlatego markdown jest bezpieczniejszy (ale nie 100%). Odnośnie walidacji, frontend to tylko kosmetyka, prawdziwa walidacji MUSI być pod stronie backendu.

1
Anatolijus napisał(a):

Pytanie do osób, które pracowały nad czymś podobnym. Czy zapis markdowna oraz html do bazy danych to jest coś naturalnego?

A jakie to ma znaczenie?

Napisz program tak żeby działał. To czy w bazie siedzi markdown, czy html, czy binarka to nie ma znaczenia.

Spectra napisał(a):

Przede wszystkim na backendzie przed jakimkolwiek zapisem musisz zwalidować tego htmla czy nie zawiera przypadkiem jakiś niechcianych rzeczy typu znaczników script itd.

To się robi przy wyświetlaniu.

Chęć walidowania tego przy dodawaniu może informować o pewnym złym symptomie, mianowicie o takim przekonaniu że "wszystko co jest w bazie jest pure good, i nie trzeba z tym nic robić". To jest średnie, bo w bazie oczywiście będzie input usera, który trzeba prawidłowo obsłużyć w odpowiednim miejscu (a nie automatycznie zakładać że dane w bazie są "nieskazitelnie czyste"). Dlatego takie coś jak <script> w html'u trzeba ogarnąć przy wyświetlaniu, np pokazać go jako &lt;script&gt;.

1

@Riddle co Ty gadasz? walidacja przy wyświetlaniu na froncie jako jedyna? Już lepiej nic nie mów.......

A co jeśli ktoś wrzuci do bazy chociażby wspomniany przez Ciebie tag <script>? Przy Twoich założeniach będzie mógł. Czyli jeśli jest to atakujący to ma full-access do DB.

Input usera powinno się walidować w trzech miejscach:

  • na wejściu do bazy (zapisując dany rekord)

  • na wyjściu z bazy (pobierając rekord)

  • wstawiając rekord do pola tekstowego na froncie

    A podejście typu "wszystko w bazie jest pure good" jest podejściem jaknajbardziej słusznym.

1
mustang_ex napisał(a):

@Riddle co Ty pierdzielisz? walidacja przy wyświetlaniu na froncie? Już lepiej nic nie mów.......

A co jeśli ktoś wrzuci do bazy chociażby wspomniany przez Ciebie tag <script>? Przy Twoich założeniach będzie mógł. Czyli jeśli jest to atakujący to ma full-access do DB.

W samej bazie nic się nie stanie (po prostu trafi string do kolumny), a w widoku to się wyświetli jako &lt;script&gt; i też nic się nie stanie.

To o czym mówisz, że "trzeba sanitować" to jest bug wynikając z niepoprawnego wyświetlania widoku (podatnego na xss) albo niepoprawnego budowania sqli (sql injection). Jeśli masz kod podatny na takie błędy, to faktycznie ktoś mógłby wprowadzić złowrogą daną i próbować zaatakować serwis. Ale odpowiedzią na to nie jest filtrować dane na wejściu, tylko oczywiście poprawić widok i budowanie sqli tak żeby nie były podatne na takie błędy.

1

Zainsertowanie inputu usera do kolumny string w bazie nie zrobi nic złego.

To zależy. Od enkodowania właśnie.

1
mustang_ex napisał(a):

Zainsertowanie inputu usera do kolumny string w bazie nie zrobi nic złego.

To zależy. Od enkodowania właśnie.

Nie. W bazie nie zrobi nic złego, niezależnie jakie encodowanie masz.

Może zrobić coś złego jak wyciągniesz te dane z bazy i spróbujesz je niepoprawnie wyświetlić. Jak masz poprawnie budujesz widok (i poprawnie traktujesz html i plaintext), oraz korzystasz z prepared statements w sqlu, to nie ważne jakie dane użytkownik wprowadzi - żadnej w luki w zabezpieczeniach nie masz.

1

@hzmzp

Jest to jak najbardziej dobra i powszechna praktyka. Niestety problem lezy gdzie indziej. Na początek, kto to może załadować? Jeżeli to jest autoryzowana, pewna osoba to jest OK. Jeżeli jest to random z internetu to na 100% znajdzie się taki, który doda złośliwy kod. Dlatego markdown jest bezpieczniejszy (ale nie 100%). Odnośni walidacji, frontend to tylko kosmetyka, prawdziwa walidacji MUSI być pod stronie backendu.

ale co ty chcesz walidowac na tym backendzie?

Spectra napisał(a):

Robiłem coś takiego, mówię tutaj o zapisie HTML`a do bazy (komentarze userów) nie widzę w tym nic złego, jeśli to się robi z głową.
Przede wszystkim na backendzie przed jakimkolwiek zapisem musisz zwalidować tego htmla czy nie zawiera przypadkiem jakiś niechcianych rzeczy typu znaczników script itd.
Można ustawić whiteliste dozwolonych znaczników html i jeśli pojawi się jakiś nie dozwolony to nie zapisywać tego, są chyba gotowe libki do tego.

@Spectra

Sprawdzanie czy nie zawiera niechcianych znaczników?

Zakładasz z góry że ten html string jest unsafe i że nie uda ci się go w pełni zwalidować i po prostu frontend renderuje go jako zwykły tekst, a nie HTML.

Nie jeden programista już robił swoją koślawą implementacje takich checkerów a'la if (html.ToLower().Contains("script")) itd,. ale po prostu to nie ma sensu - ciężko zrobić 100% pokrycia, przeglądarki i sam HTML to jest moving target (ciągle się zmieniają), a w dodatku mogą również zawierać bugi np. w wersji XYZ Chromium jest możliwe zrobienie RCE za pomocą zwykłego <b>

Stosuj dojrzałe ORMy/libki do obsługi bazki i parametrized queries, a na froncie renderuj to jako zwykły tekst, a nie HTML i powinno być ok bez żadnych operacji na literkach.

@Riddle ma rację pisząc

To o czym mówisz, że "trzeba sanitować" to jest bug wynikając z niepoprawnego wyświetlania widoku (podatnego na xss) albo niepoprawnego budowania sqli (sql injection). Jeśli masz kod podatny na takie błędy, to faktycznie ktoś mógłby wprowadzić złowrogą daną i próbować zaatakować serwis. Ale odpowiedzią na to nie jest filtrować dane na wejściu, tylko oczywiście poprawić widok i budowanie sqli tak żeby nie były podatne na takie błędy.

0

@WeiXiao czemu if (html.ToLower().Contains("script")) jest wg Ciebie "koślawe"?

0

@mustang_ex

Przecież napisałem :P

ale po prostu to nie ma sensu - ciężko zrobić 100% pokrycia, przeglądarki i sam HTML to jest moving target (ciągle się zmieniają), a w dodatku mogą również zawierać bugi np. w wersji XYZ Chromium jest możliwe zrobienie RCE za pomocą zwykłego <b>

0

@WeiXiao chociaż by to, żeby po wejściu na strone nie leciał redirect na pornhuba?

0

Mam wrażenie, że ta rozmowa poszła w zupełnie niepotrzebnym kierunku.

Do komentarzy używamy markdowna.

Ok, świetnie. Czyli mamy pogrubianie, kursywę, jakieś linki, listy itp.

Czy zapis markdowna oraz html do bazy danych to jest coś naturalnego

Czekaj. Czemu chcesz zapisywać HTML do bazy? Przecież masz bezpieczny markdown. Po prostu zapisz markdowna do bazy, a renderuj do HTML dopiero, jak to leci na widok. Albo nawet na froncie użyj jakiejś libki do wyświetlania tego (robiłem tak w jednym projekcie - serwer tworzy markdowna, a dopiero front to przerabia javascriptem na HTML - wada - wymóg JS).

Pole typu string byłoby tylko potrzebne do uzupełnienia ekranu edytora komentarza

W sensie masz jakiś komponent edytora, który wymaga HTML i nie działa z md?

2
kelog napisał(a):

Czekaj. Czemu chcesz zapisywać HTML do bazy? Przecież masz bezpieczny markdown. Po prostu zapisz markdowna do bazy, a renderuj do HTML dopiero, jak to leci na widok. Albo nawet na froncie użyj jakiejś libki do wyświetlania tego (robiłem tak w jednym projekcie - serwer tworzy markdowna, a dopiero front to przerabia javascriptem na HTML - wada - wymóg JS).

W Markdown można pisać html. Np taki tekst:

Witaj **bold**

<b>foo</b>

Hello *italic*

to jest poprawny markdown.

Poza tym znowu robisz jakieś zdziwianie z konceptem "bezpieczny markdown". Nie ma czegoś takiego jak bezpieczny albo niebezpieczny input. Input to input. Jasne, są ataki takie jak XSS i SQL Injection które kojarzą się z "wstrzykiwaniem kodu w input", ale to nie jest podatnośc którą programy mają "by default". Tą podatność tworzą programiści poprzez niepoprawne obsługiwanie wartości - np. ktoś skleja SQL i nie poprawnie łączy SQL i plaintext. Jeśli ktoś ma taką podatność - to niektórzy próbują ją naprawić źle - np. dodając "walidację"; ale należy ją naprawić poprawnie - czyli po prostu usunąć podatność, np odpowiednio enkodując wartości w momencie ich użycia (nie przed). Podobnie jest z XSS'em, jak sobie "ślepo" wyświetlisz input usera w swojej stronie HTML, to to jest podatność na XSS. Ale odpowiedzią na to nie jest "dodać walidację" kiedy input wchodzi do bazy; tylko oczywiście odpowiednie zbudowanie widoku - czyli tam gdzie doklejasz input usera do HTML'a, tam trzeba go poprawnie zaenkodować.

1
Anatolijus napisał(a):

Jest sobie system komentarzy na stronie internetowej. Użytkownik może edytować swoje komentarze. Do komentarzy używamy markdowna. Pytanie do osób, które pracowały nad czymś podobnym. Czy zapis markdowna oraz html do bazy danych to jest coś naturalnego? Generowanie html z markdowna odbywałoby się przy tworzeniu i edytowaniu. Pole typu string byłoby tylko potrzebne do uzupełnienia ekranu edytora komentarza.

  1. Zapisz treść którą dodaje użytkownik w bazie, w takiej formie w jakiej ją dostajesz.
  2. Na backendzie albo na froncie (nie istotne) zamień Markdown na HTML i wyświetl.
  3. Po zamienieniu markdownu na html skorzystaj z parsera HTML żeby usunąć tagi których nie chcesz, np <script>, albo ewentualnie wyświetl go jako plain tekst: &lt;script&gt;.
  4. Jeśli parsowanie przy widoku sprawia za duży problem z parsowaniem dodaj cache (cache może być w ramie, na plikach, albo też w bazie jak chcesz).

PS: Przy czym cache to nie koniecznie musi być redis czy coś takiego, może być po prostu zwykła zmienna która trzyma tą wartość zamiast liczyć ją ponownie.

1

Jak zapiszesz jako html będziesz miał wszystkie te problemy o których mówią koledzy, plus jeszcze jeden, jak będziesz chciał cokolwiek jak kolwiek kiedy kolwiek zmienić, to nie bedzie się dało bo html to html, a przeparsować tak skomplikowany format cieżko bezbłednie. Jak zapiszesz sobie w nie jako html, tylko co prostszego, nie jesteś tak uwiązany.

1
_flamingAccount napisał(a):

Jak zapiszesz jako html będziesz miał wszystkie te problemy o których mówią koledzy, plus jeszcze jeden, jak będziesz chciał cokolwiek jak kolwiek kiedy kolwiek zmienić, to nie bedzie się dało bo html to html, a przeparsować tak skomplikowany format cieżko bezbłednie. Jak zapiszesz sobie w nie jako html, tylko co prostszego, nie jesteś tak uwiązany.

Przecież on dostaje HTML 😐 Tak czy tak będzie musiał go przeparsować.

1 użytkowników online, w tym zalogowanych: 0, gości: 1