Zapobieganie XSS w aplikacji internetowej JSP / Servlet

Jak zapobiec atakom XSS w aplikacji internetowej JSP/Servlet?

Author: BalusC, 2010-04-17

8 answers

XSS można zapobiec w JSP za pomocą JSTL <c:out> tag lub fn:escapeXml() funkcja EL podczas (re)wyświetlania kontrolowanego przez użytkownika wejścia. Obejmuje to parametry żądania, nagłówki, pliki cookie, adres URL, treść itp. Wszystko, co wyodrębnisz z obiektu request. Również kontrolowane przez użytkownika Dane wejściowe z poprzednich żądań, które są przechowywane w bazie danych, muszą zostać zabezpieczone podczas ponownego wyświetlania.

Na przykład:

<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>

To ucieknie postaci, które może zniekształcić renderowany HTML, taki jak <, >, ", ' oraz & do encji HTML/XML takich jak &lt;, &gt;, &quot;, &apos; i &amp;.

Zauważ, że nie musisz przed nimi uciekać w kodzie Java (Servlet), ponieważ są tam nieszkodliwe. Niektóre mogą zdecydować się na uniknięcie ich podczas przetwarzania request (Jak to robisz w Servlet lub Filter) zamiast przetwarzania response (Jak to robisz w JSP), ale w ten sposób możesz ryzykować, że niepotrzebnie dane zostaną & staje się &amp;amp; zamiast &amp; i ostatecznie użytkownik końcowy zobaczy, że &amp; jest prezentowany), lub że dane przechowywane w DB stają się nie do przeniesienia (np. podczas eksportowania danych do JSON, CSV, XLS, PDF, itp., które w ogóle nie wymagają HTML-escapingu). Stracisz również kontrolę społeczną, ponieważ nie wiesz już, co użytkownik faktycznie wypełnił. Jako administrator witryny naprawdę chcesz wiedzieć, którzy użytkownicy / adresy IP próbują wykonywać XSS, abyś mógł je łatwo śledzić i podejmij odpowiednie działania. Ucieczka podczas przetwarzania żądań powinna być używana tylko i wyłącznie wtedy, gdy naprawdę trzeba naprawić wrak pociągu źle rozwiniętej starszej aplikacji internetowej w jak najkrótszym czasie. Mimo to powinieneś ostatecznie przepisać swoje pliki JSP, aby stały się bezpieczne dla XSS.

Jeśli chcesz ponownie wyświetlić dane wejściowe sterowane przez użytkownika jako HTML, w którym chcesz zezwolić tylko na określony podzbiór znaczników HTML, takich jak <b>, <i>, <u>, itp., Następnie trzeba odkażać wprowadzanie przez białą listę. Możesz do tego użyć parsera HTML, takiego jak Jsoup. Ale znacznie lepiej jest wprowadzić przyjazny dla człowieka język znaczników, taki jak Markdown (używany również tutaj na Stack Overflow). Następnie możesz użyć parsera Markdown, takiego jak CommonMark . Posiada również wbudowane możliwości dezynfekcji HTML. Zobacz także Szukam kodera HTML Java .

Po stronie serwera jedynym problemem w odniesieniu do baz danych jest SQL injection profilaktyka. Musisz upewnić się, że nigdy nie łączysz bezpośrednio kontrolowanego przez użytkownika wejścia w zapytaniu SQL lub JPQL i że używasz sparametryzowanych zapytań do końca. W JDBC oznacza to, że należy używać PreparedStatement zamiast Statement. W Warunkach JPA, użycie Query.
W przeciwieństwie do JSP / Servleta, Java EE nie jest w pełni kompatybilna z architekturą Java EE. Ma wbudowany XSS (i CSRF!) prewencja ponad wszystko. Zobacz też CSRF, XSS i SQL Injection Attack prevention w JSF .
 87
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 07:33:34

How-to-prevent-xss był pytany kilka razy. Wiele informacji znajdziesz w StackOverflow. Ponadto strona internetowa OWASP zawiera ściągawkę prewencyjną XSS , którą powinieneś przejść.

Na bibliotekach do wykorzystania, biblioteka ESAPI OWASP ma smak Javy. Powinieneś to wypróbować. Poza tym, każdy framework, którego używasz, ma pewną ochronę przed XSS. Ponownie strona OWASP zawiera informacje na temat najpopularniejszych frameworków, więc polecam przejrzeć miejscu.

 12
Author: Sripathi Krishnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-17 15:38:34

Miałem wielkie szczęście z OWASP Anti-Samy i doradcą AspectJ na wszystkich moich kontrolerach sprężynowych, które blokują XSS przed wejściem.

public class UserInputSanitizer {

    private static Policy policy;
    private static AntiSamy antiSamy;

    private static AntiSamy getAntiSamy() throws PolicyException  {
        if (antiSamy == null) {
            policy = getPolicy("evocatus-default");
            antiSamy = new AntiSamy();
        }
        return antiSamy;

    }

    public static String sanitize(String input) {
        CleanResults cr;
        try {
            cr = getAntiSamy().scan(input, policy);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return cr.getCleanHTML();
    }

    private static Policy getPolicy(String name) throws PolicyException {
        Policy policy = 
            Policy.getInstance(Policy.class.getResourceAsStream("/META-INF/antisamy/" + name + ".xml"));
        return policy;
    }

}

Możesz uzyskać doradcę AspectJ z tego postu stackoverflow

Myślę, że jest to lepsze podejście niż c: out szczególnie, jeśli robisz dużo javascript.

 11
Author: Adam Gent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:09

Zarządzanie XSS wymaga wielu walidacji, danych od strony klienta.

  1. walidacje wejściowe (Walidacja formularza) po stronie serwera. Istnieje wiele sposobów, aby to zrobić. Możesz spróbować JSR 303 bean validation(walidator hibernate) lub Esapi Input Validation framework. Chociaż sam tego nie próbowałem (jeszcze), istnieje adnotacja, która sprawdza Bezpieczny html (@SafeHtml) . W rzeczywistości można użyć walidatora Hibernate Z Spring MVC for bean walidacje - > Ref
  2. żądania adresów URL - dla wszystkich żądań HTTP użyj pewnego rodzaju filtra XSS. Użyłem poniższej aplikacji internetowej i zajmuje się czyszczeniem żądania adresu URL HTTP- http://www.servletsuite.com/servlets/xssflt.htm
  3. Dane wyjściowe / html zwrócone do klienta(patrz powyżej na Wyjaśnienie @ BalusC).
 7
Author: MasterV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-30 00:18:29

Sugerowałbym regularne testowanie luk w zabezpieczeniach za pomocą zautomatyzowanego narzędzia i naprawianie tego, co znajdzie. O wiele łatwiej jest zasugerować bibliotekę, która pomoże w konkretnej Luce, niż w przypadku wszystkich ataków XSS w ogóle.

Skipfish to narzędzie open source od Google, które badałem: znajduje sporo rzeczy i wydaje się warte użycia.

 3
Author: Sean Reilly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-17 16:03:46

Nie ma łatwego, wyjmowanego z pudełka rozwiązania przeciwko XSS. API OWASP ESAPI ma pewne wsparcie dla ucieczki, które jest bardzo przydatne, i mają biblioteki znaczników.

Moim podejściem było zasadniczo rozszerzenie znaczników stuts 2 w następujący sposób.

  1. zmodyfikuj znacznik s: property, aby mógł on przyjmować dodatkowe atrybuty określające, jaki rodzaj ucieczki jest wymagany (escapeHtmlAttribute="true" itd.). Wiąże się to z utworzeniem nowej właściwości i klas PropertyTag. Klasa właściwości używa OWASP ESAPI api dla ucieczki.
  2. Zmień szablony freemarkera, aby użyć nowej wersji właściwości s: i ustaw ucieczki.

Jeśli nie chcesz modyfikować klas w kroku 1, innym rozwiązaniem byłoby zaimportowanie znaczników ESAPI do szablonów freemarkera i ucieczka w razie potrzeby. Następnie, jeśli chcesz użyć znacznika S:property w swoim JSP, owiń go tagiem i ESAPI.

Napisałem bardziej szczegółowe wyjaśnienie proszę.

Http://www.nutshellsoftware.org/software/securing-struts-2-using-esapi-part-1-securing-outputs/

Zgadzam się, że wyjście ucieczki nie jest idealne.

 3
Author: brett.carr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-13 02:38:46

Moja osobista opinia jest taka, że powinieneś unikać używania stron JSP/ASP/PHP / etc. Zamiast tego wyjście do API podobnego do SAX (tylko przeznaczone do wywołania, a nie Obsługi). W ten sposób istnieje pojedyncza warstwa, która musi tworzyć dobrze uformowane wyjście.

 2
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-19 13:21:06

Jeśli chcesz automatycznie uciec wszystkie zmienne JSP bez konieczności jawnego zawijania każdej zmiennej, możesz użyć rozdzielacza El Jak szczegółowo opisano tutaj z pełnym źródłem i przykładem (JSP 2.0 lub nowszy), i omówiono bardziej szczegółowo tutaj:

Na przykład, używając wyżej wymienionego rozdzielacza el, Twój kod JSP pozostanie taki sam, ale każda zmienna zostanie automatycznie uniknięta przez rozdzielacz

...
<c:forEach items="${orders}" var="item">
  <p>${item.name}</p>
  <p>${item.price}</p>
  <p>${item.description}</p>
</c:forEach>
...

Jeśli chcesz wymusić domyślnie ucieczkę w Spring, można to również rozważyć, ale to nie umyka el expressions, tylko Tag output, myślę, że:

Http://forum.springsource.org/showthread.php?61418-Spring-cross-site-scripting&p=205646#post205646

Uwaga: inne podejście do ucieczki EL, które wykorzystuje transformacje XSL do preprocesowania plików JSP, można znaleźć tutaj:

Http://therning.org/niklas/2007/09/preprocessing-jsp-files-to-automatically-escape-el-expressions/

 2
Author: Brad Parks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-17 13:13:34