jak odświeżyć plik cookie JSESSIONID po zalogowaniu

Produkt, nad którym pracuję, przeszedł trudny audyt bezpieczeństwa przez potencjalnego klienta i jest zdenerwowany, że Tomcat ustawia plik cookie JSESSIONID przed uwierzytelnieniem. Oznacza to, że Tomcat ustawia ten plik cookie, gdy ładuje się nasza bezpaństwowa strona logowania, ale przed zalogowaniem.

Sugerują jedno z poniższych:

  1. wydanie nowego pliku cookie JSESSIONID po zalogowaniu
  2. zapobiega ustawieniu pliku cookie JSESSIONID w pierwszej kolejności na stronie logowania (tj. przed uwierzytelnieniem zdarzyło się)

Przeglądałem wszystko, co związane z JSESSIONID na tej stronie i nie mogę znaleźć łatwej odpowiedzi. Mam tylko nadzieję na jakieś pomysły. Moje najlepsze rozwiązania dla każdego to:

  1. zaraz po zalogowaniu, Sklonuj sesję (bez id), kopiując wszystkie atrybuty, unieważniając starą sesję, tworząc nową, kopiując wartości, powiązując ją z żądaniem i mając nadzieję, że zadziała.
  2. utworzyć filtr serwleta na samym końcu łańcucha, który usuwa plik cookie JSESSIONID przed wczytaniem strony logowania. A potem mam nadzieję, że żądanie logowania zadziała bez zestawu JSESSIONID.

Muszę się przespać, ale będę próbował tego rano. Byłoby wspaniale uzyskać opinie lub lepsze sugestie od ludzi o wiele mądrzejszych niż ja-takich jak ty!

Niezależnie od tego, zamieszczę tutaj Moje wyniki, ponieważ wydaje się, że wiele innych osób chciało zrobić coś podobnego.

Author: Adam Rackis, 2011-11-17

10 answers

Nie odświeżysz się po, ale tuż przed. Podczas wykonywania operacji logowania najpierw wykonaj:

HttpSession session = request.getSession(false);
if (session!=null && !session.isNew()) {
    session.invalidate();
}

To zrób:

HttpSession session = request.getSession(true); // create the session
// do the login (store the user in the session, or whatever)

FYI to, co rozwiązujesz tą sztuczką jest http://www.owasp.org/index.php/Session_Fixation

Wreszcie możesz wyłączyć automatyczne tworzenie sesji i utworzyć sesję tylko wtedy, gdy naprawdę jej potrzebujesz. Jeśli używasz JSP, robisz to przez:

<%@page contentType="text/html"
        pageEncoding="UTF-8"
        session="false"%>
 36
Author: cherouvim,
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-11-17 11:10:56

Nie mogę skomentować powyższej odpowiedzi @ cherouvim, ponieważ nie mam wystarczającej ilości punktów. Nowy identyfikator sesji powinien być ustawiony " po " pomyślnym zalogowaniu się użytkownika, aby uniknąć utrwalenia sesji. Spróbuję wyjaśnić moje rozumowanie.

Utrwalenie sesji skutecznie oznacza, że atakujący w jakiś sposób oszukał użytkownika, aby użył wartości znanej atakującemu. Dla uproszczenia Załóżmy, że atakujący podszedł do biurka użytkownika, użył Firebuga i edytował plik cookie użytkownika. Teraz, gdy użytkownik loguje użytkownik zostanie zalogowany za pomocą pliku cookie kontrolowanego przez atakującego. Ponieważ atakujący również zna tę wartość, odświeży przeglądarkę, a zasoby zmapowane do tego identyfikatora sesji (zasoby ofiary) zostaną mu podane. To fiksacja sesji. Zgadza się?

Powiedzmy, że przeprowadziliśmy sesję.Unieważnij przed zalogowaniem się użytkownika ofiary. Powiedzmy, że plik cookie początkowo miał wartość abc. Przy uruchomieniu sesji .invalidate wartość abc jest usuwana z serwera sesja.

Teraz przychodzi moment, w którym się nie zgadzam. Sugerujesz wygenerowanie nowej sesji zanim użytkownik faktycznie się zaloguje (wpisuje nazwę użytkownika i hasło oraz kliknie submit). Bez wątpienia spowoduje to wygenerowanie nowego pliku cookie, ale będzie on w przeglądarce użytkownika przed zalogowaniem się. Jeśli więc atakujący może ponownie edytować plik cookie "prelogin", atak nadal trwa, ponieważ ten sam plik cookie będzie używany nawet po zalogowaniu się użytkownika.

Myślę, że to jest poprawne / align = "left" /

  • User does a GET / login.html
  • powrót do strony logowania z dowolnym ciasteczkiem, który znajduje się obecnie w przeglądarce
  • użytkownik wpisuje dane uwierzytelniające i kliknie submit
  • Aplikacja weryfikuje poświadczenia
  • po stwierdzeniu, że poświadczenia były poprawne. sesja.invalidate() jest uruchamiane ..niszczenie starego ciastka.
  • Wygeneruj teraz nowy plik cookie za pomocą request.getSession (true)

Oznacza to, że nawet jeśli napastnik udaje się namówić Cię do użycia kontrolowanej wartości przed zalogowaniem się, nadal jesteś protected..as aplikacja wymusza zmianę wartości po zalogowaniu.

Oto dobry blog na ten temat - https://blog.whitehatsec.com/tag/session-fixation/

 4
Author: LDE,
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
2014-01-06 20:52:53

Wykonałem następujący sposób, aby zregenerować nową sesję ze starej sesji. Mam nadzieję, że skorzystasz z tego.

private void regenerateSession(HttpServletRequest request) {

    HttpSession oldSession = request.getSession();

    Enumeration attrNames = oldSession.getAttributeNames();
    Properties props = new Properties();

    if (attrNames != null) {
        while (attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            props.put(key, oldSession.getAttribute(key));
        }

        //Invalidating previous session
        oldSession.invalidate();
        //Generate new session
        HttpSession newSession = request.getSession(true);
        attrNames = props.keys();

        while (attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            newSession.setAttribute(key, props.get(key));
        }
    }
 3
Author: harsha89,
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
2014-11-24 20:08:39

Czy problem polega na tym, że JSESSIONID jest widoczny w przeglądarce lub że w ogóle jest ustawiany w pliku cookie? Zakładam, że to drugie w Twoim przypadku.

1.wydanie nowego pliku cookie JSESSIONID po zalogowaniu

Jest to domyślne zachowanie Tomcat , jeśli przełączysz się z http na https w momencie logowania. Stary jest odrzucany, a nowy jest generowany.

Jeśli sam login jest ponad http, to chyba kolejny problem bezpieczeństwa dla audytorów ;)

Czy wszystkie Twoje strony są przez https?

 1
Author: JoseK,
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-11-17 11:20:55

Znalazłem dwie rzeczy, które mogą pomóc innym.

  1. Jeśli używasz Apache Wicket, istnieje na to rozwiązanie po wersji 1.4. Moja aplikacja jest nadal na 1.3, więc nie zdawałem sobie sprawy, ale byłem w stanie z powrotem port go bardzo łatwo w mojej klasie WebSession. Wicket 1.4 dodaje metodę replaceSession () do WebSession, która działa świetnie. Możesz zadzwonić zaraz po uwierzytelnieniu, a otrzymasz nowy identyfikator JSESSIONID. To w zasadzie rozwiązało ten problem dla mnie. Więcej informacji tutaj: https://issues.apache.org/jira/browse/WICKET-1767.

  2. Po wersji 5.5.29 dostępny jest Apache Tomcat valve, który można dodać do kontekstu.xml. Zajmie się wydaniem nowego identyfikatora JSESSIONID po uwierzytelnieniu. Więcej informacji można znaleźć tutaj: https://issues.apache.org/bugzilla/show_bug.cgi?id=45255 . Wejście do zaworu wyglądałoby tak: <Valve className="org.apache.catalina.authenticator.FormAuthenticator" changeSessionIdOnAuthentication="true"/>

 1
Author: Nathan Beach,
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-11-18 17:07:26

HttpServletRequest.changeSessionId() może być użyty do zmiany identyfikatora sesji w dowolnym momencie.

 1
Author: bhawnesh dipu,
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
2018-02-12 15:08:09

Podczas używania sprężyny należy użyć SessionFixationProtectionStrategy.

<property name="sessionAuthenticationStrategy" ref="sas"/>
...
<bean id="sas" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>

Podczas sprawdzania kodu źródłowego , zobaczysz, że jest to podobne do podejścia harsha89: będzie

  1. Utwórz nową sesję
  2. przenoszenie atrybutów starej sesji.
 0
Author: Matthias M,
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-02-20 13:38:31

Jeśli używasz Tomcat i chcesz zastosować to globalnie do wszystkich serwletów, które używają mechanizmu uwierzytelniania Tomcat, możesz napisać zawór, aby wymusić to zachowanie, jak pokazano w tym przykładowym kodzie .

 0
Author: David Leppik,
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-03-29 20:14:45

Jeśli używasz starszej wersji jbossa, takiej jak jboss 4, po prostu wywołaj żądanie.getSession (true) po sesji.wywołanie invalidate () nie zmieni identyfikatora sesji.

Jeśli nie chcesz używać valve i chcesz zmienić ID sesji w klasie action to samo może być zarchiwizowane za pomocą reflection, ponieważ CatalinaRequest nie będzie dostępny bezpośrednio w twojej klasie action.

Przykładowy kod

private HttpSession changeSessionId( HttpServletRequest request )
{
    HttpSession oldSession = request.getSession( false );
    HttpSession newSession = null;

    try
    {
        //get all cookies from request
        Cookie[] cookies = request.getCookies();

        //Get all attribute from old session
        Enumeration< Object > attrNames = oldSession.getAttributeNames();

        Properties attributFromOldSession = new Properties();

        while ( attrNames.hasMoreElements() )
        {
            String key = (String)attrNames.nextElement();
            attributFromOldSession.put( key, oldSession.getAttribute( key ) );
        }

        //Actual logic to change session id

        Field catalinaRequestField;

        //Getting actual catalina request using reflection
        catalinaRequestField = request.getClass().getDeclaredField( "request" );
        catalinaRequestField.setAccessible( true ); // grant access to (protected) field
        Request realRequest = (Request)catalinaRequestField.get( request );

        //Invalidating actual request
        realRequest.getSession( true ).invalidate();
        realRequest.setRequestedSessionId( null );
        realRequest.clearCookies();

        //setting new session Id
        realRequest.setRequestedSessionId( realRequest.getSessionInternal( true ).getId() );

        //Put back the cookies
        for ( Cookie cookie : cookies )
        {

            if ( !"JSESSIONID".equals( cookie.getName() ) )
            {
                realRequest.addCookie( cookie );
            }
        }

        // put attribute from old session
        attrNames = attributFromOldSession.keys();

        while ( attrNames.hasMoreElements() )
        {
            String key = (String)attrNames.nextElement();
            newSession.setAttribute( key, attributFromOldSession.get( key ) );
        }
    }
    catch ( Exception e )
    {
        e.printStackTrace();
    }
    return newSession;

}
 0
Author: Rahul Suman,
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-19 08:51:12
session=request.getSession(true);
Enumeration keys = session.getAttributeNames();     
HashMap<String,Object> hm=new HashMap<String,Object>();  
while (keys.hasMoreElements())
{
  String key = (String)keys.nextElement();
  hm.put(key,session.getValue(key));
  session.removeAttribute(key);      
}
session.invalidate();
session=request.getSession(true);
for(Map.Entry m:hm.entrySet())
{
  session.setAttribute((String)m.getKey(),m.getValue());  
  hm.remove(m);
}  
 -1
Author: sachin berad,
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
2016-12-31 06:44:45