Bezpieczeństwo, nie tylko w świecie Javy

Wpis dodany 07 września 2009 o godz. 19:56:11 w kategorii Groovy, Java, Security, Techblog.

Myślę, że ostatnio ujawniony wyciek danych z serwisu Wykop.pl uświadomił niektórym, jak niebezpieczne może być używanie tego samego hasła w wielu miejscach, z bankiem i Allegro włącznie. Na temat samej administracji Wykopu wypowiadać się za bardzo nie chcę, wszakże ponoć nie kopie się leżącego. Jeśli jednak to prawda, że wyciek nastąpił już jakiś czas temu i w dodatku osoby zarządzające serwisem miały tego świadomość, brak informacji dla użytkowników o tym fakcie to raczej sprawa dla prokuratora i prawników.

Osobną kwestią jest używanie prawdziwych danych produkcyjnych na potrzeby nowej, testowej wersji serwisu. Osobiście nie widzę w tym nic złego (inni widzą). Projektując np. forum internetowe zamiast tysiąca postów z "lorem ipsum" lepiej mieć dostęp choćby do setki wpisów rzeczywistych użytkowników, inwencja niektórych osób może bowiem naprawdę zaskoczyć twórców oprogramowania ;). Oczywiście takie dane muszą zostać oczyszczone z "wrażliwych" informacji (a takimi są chociażby hasła). Całkiem możliwe też, że konieczne okaże się zamazanie danych osobowych, no ale to już też bardziej kwestia prawna. Swoją drogą myślę, że Wykop powinien spodziewać się w najbliższym czasie kontroli z GIODO.

Sprawą, która zwróciła moją uwagę, jest sposób trzymania hasła w systemie Wykopu. Niewiele trzeba, aby zorientować się, że hasła były kodowane za pomocą SHA1. Jest to zabezpieczenie zdecydowanie niewystarczające, chociaż dobrze, że przynajmniej ono zostało wdrożone. To, że istnieją systemy (i to jall... kie duże), które trzymają hasła w postaci jawnej, świadczy tylko o ich twórcach (jednak warto brać poprawkę na to, że w tym wypadku mamy sporo tzw. "legacy code"). To żadna filozofia użyć "salta" w nowo powstających systemach (a takim jest Wykop, to nie jest system bankowy z lat 60-tych, którego działania nie rozumie właściwie nikt). Generalnie dobrym pomysłem jest generowanie innego salta dla każdego hasła, wtedy po wyliczeniu sha1(salt + hasło) trudno będzie poznać, że dwóch użytkowników posiada identyczne hasła. Oczywiście baza zawsze może wyciec (nieprawdaż?), zatem doklejenie do hasła i generowanego salta jeszcze jakieś stałej zapisanej w "propertiesach" aplikacji powinno nas wystarczająco zabezpieczyć. Oczywiście żadne zabezpieczenia nie uchronią przed głupotą i brakiem wyobraźni, wszakże dla niektórych "qwerty" to silne hasło.

O ile braki w wiedzy na temat bezpieczeństwa wśród zwykłych użytkowników można wybaczyć (ale nie zaakceptować), o tyle wśród programistów brak takiej świadomości może prowadzić do sporych luk w bezpieczeństwie. Weźmy np. takie tagi JSP (JavaServer Pages) i EL (expression language). Domyślnie wszystkie teksty są "escape'owane", czyli jeśli użytkownik nazywa się <script>alert('xss')</script>, to właśnie naszym oczom ukaże się taka nazwa, a nie javascriptowy alert. Pisanie własnych tagów powoduje jednak, że mamy do czynienia z tworzeniem HTML-a w kodzie Javy. Nie wolno wtedy zrobić czegoś takiego:

    @Override
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) getJspContext();
        JspWriter out = pageContext.getOut();
        out.println("" + someMessage.getBody() + "");
    }

Oprócz tego, że w ten sposób de facto przenosimy warstwę widoku do (zwykłych) klas Javy (a tego robić nie chcemy i nie powinniśmy, skryptlety są przecież passé), a nasz webmaster nie wie, co ma z takim tagiem zrobić, to dodatkowo prosimy się o XSS, nie mamy bowiem w takim wypadku żadnej walidacji. Lepiej zapisać tekst do wyświetlenia w kontekście JSP i wyświetlić go bezpiecznie za pomocą EL na samej stronie.

I jeszcze jeden przypadek, który nasunął mi się po lekturze sierpniowego SDJ i lekturze artykułu o Groovym. Tekst jest dobrze napisany (w przeciwieństwie do paru innych), tyle że mamy tam następujący kwiatek: "GString (...) umożliwia dostęp do zmiennych z poziomu łańcuchów znaków (...) Może to mieć zastosowanie w wielu sytuacjach, np. (...) przy tworzeniu zapytań SQL". Takie podejście do pisania w SQL-u (aż by się chciało powiedzieć, że w stylu chłopców phpowców po gimnazjum) to prośba o kolejny atak, tym razem dla odmiany SQL Injection. Za nieużywanie sparametryzowanych zapytań powinno się w IT wprowadzić kary cielesne.

Trzeba też niestety uczciwie przyznać, że z wiedzą dotyczącą bezpieczeństwa (ogólnie pojętego) jest kiepsko, zwłaszcza w różnych startupach czy garażowych firmach (a i uczelnie dokładają tutaj swoją cegiełkę, a właściwie brak cegiełki). Głównym problemem dla firm jest ROI, ale inwestycja w "security" jest bardziej ubezpieczeniem, zresztą nawet w podstawowym pakiecie bardzo tanim i efektywnym w przypadku zagrożenia. No bo co to za filozofia postawić firmowy VPN, wprowadzić salt do haseł w tworzonych systemach czy używać PreparedStatement. To przecież wydawałoby się podstawy podstaw.

O javowych blogach na spóźniony BlogDay 2009

Wpis dodany 02 września 2009 o godz. 17:00:52 w kategorii Java.

Swoje święta mają administratorzy, ma liczba PI, mają zatem też blogi. Jako że wpis ten i tak ukazuje się po deadline, który przypadał na 31 sierpnia, pozwolę sobie na modyfikację także i innych punktów regulaminu (więcej informacji na temat całej akcji można znaleźć na stronie BlogDay). Czyli będzie lista blogów, ale niekoniecznie pięciu, niekoniecznie nowo odkrytych i niekoniecznie niezwiązanych z poruszaną przeze mnie tematyką, a wręcz przeciwnie.

Blog Day 2009

Swoją drogą z blogami ogólnie jest tak, że ludzie zbyt często piszą nie mając nic do przekazania. Wydaje mi się, że jednak z ludźmi zaangażowanymi w IT jest nieco inaczej - mają do przekazania całkiem sporo, lecz zbyt często kończy się to na paru wpisach, a potem blog pozostaje martwy. Z tego też powodu w Blog Day z czytnika RSS musiałem niestety wykasować sporo nieaktywnych blogów, zwłaszcza technicznych. A szkoda, bo zapowiadały się nieźle; niestety mało kto ma tyle zapału co Jacek Laskowski (który nota bene jest pośrednim twórcą i mojego bloga, ale to temat może na jakąś rocznicową notkę :).

    Subiektywnie wybrane blogi javowe:
  • Holistyczna inżynieria oprogramowania (http://art-of-software.blogspot.com) - chyba najlepszy według mnie w tym momencie polski blog javowy, stąd też zgłosiłem go do konkursu JDD 09 Java Guide. Autor nie opisuje kolejnych pięciuset frameworków webowych, ale kładzie nacisk na te aspekty pracy w świecie IT, których nie poznamy z dokumentacji ani też zapewne nie nauczymy się na studiach, niestety. Polecam, chociażby ze względu na humanistyczne zacięcie.

  • Java and neighbourhood (http://nurkiewicz.blogspot.com) - od niedawna anglojęzyczny blog Tomka Nurkiewicza. Ciekawa dla mnie tematyka, przemyślane i interesujące notki, także jeżeli chodzi o ich formę (co często jest bolączką osób "technicznych"). Może trochę za rzadko pisze i nie ma archiwum, no ale nikt nie jest doskonały.

  • Adam Bien's Weblog (http://www.adam-bien.com) - wpisy Adama w blogu są jak jego występy na konferencjach (w Polsce m.in. JDD i GeeCON) - oszczędne w formie (oraz krótkie), ale zazwyczaj z maksimum interesującej treści. Poza tym pisze często, bardzo często.

Wśród moich ulubionych blogów javowych (a nawet i czasem w czytniku) brak nazwisk takich jak Gosling czy chociażby Strachan, ciekawa treść bowiem często nie idzie w parze z zasługami danej osoby dla javowej społeczności. A Wy macie jakieś ulubione javowe zakątki w sieci, którymi chcielibyście się podzielić?

Dlaczego warto poznać Stripes Framework

Wpis dodany 24 sierpnia 2009 o godz. 20:31:32 w kategorii Java, Spring, Stripes, Techblog.

Frameworków webowych dla Javy jest mnóstwo, a wybór najlepszego to temat na wielodniowy "flame". Wicket jest na topie, w GWT nie trzeba pisać HTML-a, JSF to standard, a Struts 2 to prawie że potomek legendarnych Strutsów. Istnieje jednak framework webowy, który może nie jest aż tak bardzo popularny jak wyżej wymienione, ale warto go poznać, bo w pełni na to zasługuje. Mowa oczywiście o tytułowym Stripes Framework.

Używałem już paru szkieletów webowych, ale przy ostatnim projekcie, w którym decydowałem o wyborze technologii, moje rozważania zakończyły się wyborem tandemu Spring + Stripes. Z perspektywy czasu widzę, że akurat w tym wypadku był to bardzo dobry traf, pomimo braku wcześniejszych doświadczeń ze Stripesami (chociaż parę mądrych osób wcześniej mi mówiło, że ten framework ma właściwie wszystko, czego się wymaga od javowego frameworka webowego - i mieli oni rację).

Nie będę tutaj opisywał, jak napisać "Hello world", bo to już zrobili inni. Napiszę za to, dlaczego lubię Stripesy i dlaczego właśnie je warto użyć zamiast chociażby takiego Struts 2. Nieprzypadkowo wspominam tutaj o S2, gdyż w założeniach są to biblioteki bardzo podobne, oba frameworki są bowiem zdecydowanie akcyjne, nie komponentowe. Niektórym może się ta cecha podobać, innym mniej, ale ponoć "de gustibus non est disputandum", zresztą nie chcemy tu wspomnianego flejma.

Jedną z miłych rzeczy, które spotkamy w Stripes Framework, jest wbudowany bardzo prosty mechanizm do powtórnego wykorzystywania layoutów. Dzięki trzem prostym tagom odpada nam konieczność używania zewnętrznych rozwiązań jak Tiles czy SiteMesh. O ile ten drugi jest przyjemny w użyciu, o tyle ilość xml-a koniecznego do wyprodukowania w Tilesach przy braku konwencji skutecznie do tej biblioteki zniechęca.

Kolejną sympatyczną niespodzianką jest tag do zrobienia kontrolki wyboru z javowych enumów. Standardowo w JSTL czegoś takiego nie znajdziemy, Struts 2 też nie oferuje w tym wypadku jakiegoś gotowego rozwiązania, a jest to chyba dość popularne użycie enumów w aplikacjach internetowych. W Stripesach możemy użyć taga <stripes:options-enumeration/>, a o tym, w jaki sposób to zrobić, można doczytać w dokumentacji.

Na dokładkę zostają nam sprawy konfiguracji. Nie mamy ani kawałka xml-a poza standardowym web.xml, żadnych dodatkowych stripes.xml czy pluginów do obsługi adnotacji bądź włączenia konwencji, jeśli takowe w ogóle istnieją i nam zadziałają (tak, nieco piję tutaj do S2). Wszystko dostajemy od razu, a dzięki adnotacji @UrlBinding bardzo łatwo przyjdzie nam zrobić "ładne" URL-e. Być może są to szczegóły, ale z takich właśnie szczegółów składa się praca programisty. Zresztą pozytywnych niespodzianek jest w Stripes Framework o wiele więcej.

Ok, czy ten framework jest "świętym Graalem" wśród innych rozwiązań? Oczywiście nie, aczkolwiek trudno mi tutaj wytknąć jakiekolwiek jego niedoskonałości. Rzecz jasna nie każdemu mogą odpowiadać jsp (aczkolwiek można użyć Velocity czy FreeMaker) jako szablony, no ale to kwestia gustu. To, co mogłoby być nieco lepiej rozwiązane, to integracja ze Springiem, tzn. użycie go do tworzenia akcji tak, jak to robi Struts 2. Obecnie mamy adnotację @SpringBean (swoją drogą to już chyba jakaś konwencja nazewnicza, w Wickecie nazwa adnotacji do wstrzykiwania beanów Springa jest taka sama), natomiast nie mamy dostępu do np. @Value ze Springa 3. No ale to drobny szczegół (zresztą istnieją projekty, które pozwalają Springowi stać się zarządcą akcji stripesowych, tylko że mają one swoje wady), poza tym w wersji 1.6 (a kiedy piszę te słowa, najnowszą jest 1.5.1) możemy się i rozwiązania tej kwestii spodziewać. W każdym razie polecam przynajmniej spojrzeć przez chwilę na ten projekt, a nuż okaże się on dla Ciebie technologicznym strzałem nie w stopę, lecz w dziesiątkę.