Dlaczego dla haseł preferowany jest znak[] zamiast ciągu znaków?

W Swing, pole password ma metodę getPassword() (zwraca char[]) zamiast zwykłej metody getText() (zwraca String). Podobnie natknąłem się na sugestię, aby nie używać String do obsługi haseł.

Dlaczego String stanowi zagrożenie dla bezpieczeństwa, jeśli chodzi o hasła? Niewygodne jest używanie char[].

Author: Rakete1111, 2012-01-16

17 answers

Ciągi są niezmienne . Oznacza to, że po utworzeniu String, jeśli inny proces może zrzucić pamięć, nie ma możliwości (poza reflection), aby pozbyć się danych, zanim zacznie się garbage collection.

Za pomocą tablicy możesz jawnie wymazać dane po jej zakończeniu. Możesz nadpisać tablicę dowolną, a hasło nie będzie obecne nigdzie w systemie, nawet przed usunięciem śmieci.

Więc tak, to jest problemem bezpieczeństwa - ale nawet użycie char[] ogranicza tylko okno możliwości dla atakującego, i to tylko dla tego konkretnego rodzaju ataku.

Jak wspomniano w komentarzach, możliwe jest, że tablice przenoszone przez garbage collector pozostawią zabłąkane kopie danych w pamięci. Uważam, że jest to specyficzne dla implementacji-garbage collector może wyczyścić całą pamięć, aby uniknąć tego typu rzeczy. Nawet jeśli tak, jest jeszcze czas podczas które char[] zawiera rzeczywiste znaki jako okno ataku.

 3795
Author: Jon Skeet,
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-04-20 17:50:27

Podczas gdy inne sugestie tutaj wydają się ważne, jest jeszcze jeden dobry powód. Z plain String masz znacznie większe szanse na przypadkowe wydrukowanie hasła do logów , monitorów lub innego niebezpiecznego miejsca. Jest mniej podatny.

Rozważ to:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

Druki:

String: Password
Array: [C@5829428e
 1102
Author: Konrad Garus,
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-01-19 18:11:54

Aby zacytować oficjalny dokument, Java Cryptography Architecture guide mówi to o char[] vs. String passwords (o szyfrowaniu opartym na hasłach, ale ogólnie chodzi o hasła oczywiście):

Logiczne wydaje się gromadzenie i przechowywanie hasła w obiekcie typu java.lang.String. Jednak tu jest zastrzeżenie: Objects z typ String jest niezmienny, tzn. nie ma zdefiniowanych metod, które pozwala na zmianę (nadpisanie) lub zerowanie zawartości String po użyciu. Ta funkcja sprawia, że String obiekty nie nadają się do przechowywanie poufnych informacji bezpieczeństwa, takich jak hasła użytkowników. Ty należy zawsze zbierać i przechowywać poufne informacje dotyczące bezpieczeństwa w char zamiast tablicy.

W języku Java, w wersji 4.0 mówi się również coś podobnego (choć pierwotnie jest to w kontekście logowania):

wytyczna 2-2: nie loguj się wysoko informacje wrażliwe

Niektóre informacje, takie jak numery ubezpieczenia społecznego (SSN) i hasła, jest bardzo wrażliwy. Informacje te nie powinny być przechowywane dłużej niż to konieczne, ani tam, gdzie można to zobaczyć, nawet przez administratorów. Np. nie powinien być wysyłany do plików logów i jego obecność nie powinna być wykrywalna poprzez poszukiwania. Niektóre przemijające dane mogą być przechowywane w zmiennych strukturach danych, takich jak tablice znaków, oraz usunąć natychmiast po użyciu. Clearing struktury danych zmniejszyły się skuteczność w typowych systemach Java runtime, gdy obiekty są przenoszone w pamięci dla programisty.

Niniejsze wytyczne mają również wpływ na wdrożenie i wykorzystanie biblioteki niższego poziomu, które nie posiadają semantycznej wiedzy o danych mają do czynienia. Jako przykład, parsowanie łańcuchów niskiego poziomu biblioteka może rejestrować tekst, na którym pracuje. Aplikacja może analizować SSN z biblioteką. Stwarza to sytuację, w której SSN są dostępne dla administratorów z dostępem do plików dziennika.

 625
Author: Bruno,
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-01-17 03:20:57

Tablice znaków (char[]) można wyczyścić po użyciu, ustawiając każdy znak na zero, a łańcuchy Nie. Jeśli ktoś może w jakiś sposób zobaczyć obraz pamięci, może zobaczyć hasło w postaci zwykłego tekstu, jeśli używane są ciągi znaków, ale jeśli używane jest char[], po wyczyszczeniu danych za pomocą 0, hasło jest bezpieczne.

 311
Author: alephx,
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-03-10 17:50:52

Niektórzy uważają, że trzeba zastąpić pamięć używaną do przechowywania hasła, gdy już go nie potrzebujesz. Zmniejsza to okno czasowe, w którym osoba atakująca musi odczytać hasło z twojego systemu i całkowicie ignoruje fakt, że osoba atakująca potrzebuje już wystarczająco dużo dostępu do przejęcia pamięci JVM, aby to zrobić. Atakujący z tak dużym dostępem może złapać kluczowe zdarzenia, co czyni to całkowicie bezużytecznym (AFAIK, więc proszę mnie poprawić, jeśli jestem źle).

Update

Dzięki komentarzom muszę zaktualizować odpowiedź. Najwyraźniej istnieją dwa przypadki, w których może to dodać (bardzo) niewielką poprawę bezpieczeństwa, ponieważ skraca czas, w którym hasło może wylądować na dysku twardym. Nadal uważam, że to przesada dla większości przypadków użycia.

  • twój docelowy system może być źle skonfigurowany lub musisz założyć, że tak jest i musisz mieć paranoję na punkcie zrzutów pamięci (może być ważne, jeśli systemy nie są zarządzane przez administratora).
  • Twoje oprogramowanie musi być nadmiernie paranoiczne, aby zapobiec wyciekom danych z atakującym uzyskującym dostęp do sprzętu - używając takich rzeczy jak TrueCrypt (wycofany), VeraCryptlub CipherShed.

Jeśli to możliwe, wyłączenie zrzutu pamięci i Pliku wymiany rozwiązałoby oba problemy. Wymagają jednak uprawnień administratora i mogą zmniejszyć funkcjonalność (mniej pamięci do wykorzystania) , a wyciąganie pamięci RAM z działającego systemu nadal byłoby poprawne troska.

 187
Author: josefx,
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
2015-07-19 22:52:01
  1. ciągi znaków są niezmienne w języku Java jeśli hasło zostanie zapisane jako zwykły tekst, będzie ono dostępne w pamięci do czasu wyczyszczenia go przez Garbage collector, a ponieważ ciągi znaków są używane w Puli ciągów do ponownego użycia, istnieje duża szansa, że pozostanie w pamięci przez długi czas, co stanowi zagrożenie dla bezpieczeństwa. Ponieważ każdy, kto ma dostęp do zrzutu pamięci, może znaleźć hasło w czystym tekście
  2. rekomendacja Javy przy użyciu metody getPassword() jpasswordfield, która zwraca metodę char [] i przestarzałą metodę getText(), która zwraca hasło w jasnym tekście z podaniem przyczyny bezpieczeństwa.
  3. ToString () zawsze istnieje ryzyko wydrukowania zwykłego tekstu w pliku dziennika lub konsoli, ale jeśli użyjesz tablicy, nie wydrukujesz zawartości tablicy zamiast jej lokalizacji w pamięci.

    String strPwd = "passwd";
    char[] charPwd = new char[]{'p','a','s','s','w','d'};
    System.out.println("String password: " + strPwd );
    System.out.println("Character password: " + charPwd );
    

    String passwd: passwd

    Hasło postaci: [C@110b2345

Myśli końcowe: choć używanie char [] nie jest wystarczy, aby usunąć zawartość, aby być bardziej bezpiecznym. Sugeruję również pracę z hashowanym lub zaszyfrowanym hasłem zamiast zwykłego tekstu i wyczyszczenie go z pamięci po zakończeniu uwierzytelniania.

 121
Author: Srujan Kumar Gulla,
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-06-06 08:26:12

Nie sądzę, żeby to była słuszna sugestia, ale mogę przynajmniej zgadnąć powód.

Myślę, że motywacją jest chęć upewnienia się, że można usunąć wszystkie ślady hasła w pamięci szybko i z pewnością po jego użyciu. Za pomocą char[] można na pewno nadpisać każdy element tablicy pustym znakiem. W ten sposób nie można edytować wewnętrznej wartości String.

Ale to nie jest dobra odpowiedź; dlaczego nie po prostu upewnij się, że odniesienie do char[] lub Nie ucieka? Więc nie ma problemu z bezpieczeństwem. Ale rzecz w tym, że String obiekty mogą być intern()ed w teorii i utrzymywane przy życiu wewnątrz stałej puli. Przypuszczam, że użycie char[] zabrania takiej możliwości.

 74
Author: Sean Owen,
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-01-16 14:27:54

Odpowiedź już została udzielona, ale chciałbym podzielić się problemem, który ostatnio odkryłem z bibliotekami standardowymi Javy. Podczas gdy teraz bardzo dbają o zastąpienie ciągów haseł char[] wszędzie (co oczywiście jest dobrą rzeczą), inne krytyczne dla bezpieczeństwa DANE wydają się być pomijane, jeśli chodzi o usuwanie ich z pamięci.

Myślę np. o klasie PrivateKey . Rozważ scenariusz, w którym można załadować prywatny klucz RSA z pliku PKCS#12, używając go do wykonaj jakąś operację. W tym przypadku samo wąchanie hasła nie pomoże, o ile fizyczny dostęp do pliku klucza jest odpowiednio Ograniczony. Jako atakujący, byłoby znacznie lepiej, gdybyś uzyskał klucz bezpośrednio zamiast hasła. Pożądane informacje mogą być wyciekane, zrzuty pamięci, sesja debuggera lub pliki wymiany to tylko niektóre przykłady.

I jak się okazuje, nie ma nic, co pozwala usunąć z pamięci prywatne informacje PrivateKey , ponieważ nie ma API, które pozwalałoby na wyczyszczenie bajtów tworzących odpowiednie informacje.

Jest to zła sytuacja, ponieważ ten papier opisuje, w jaki sposób ta okoliczność może być potencjalnie wykorzystana.

Biblioteka OpenSSL na przykład nadpisuje sekcje pamięci krytycznej przed zwolnieniem kluczy prywatnych. Ponieważ Java jest zbierana ze śmieci, potrzebujemy jawnych metod, aby wyczyścić i Unieważnić prywatne informacje dla kluczy Java, które mają być zastosowane natychmiast po użyciu klucz.

 60
Author: emboss,
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-01-19 19:39:47

Jak twierdzi Jon Skeet, nie ma innego sposobu, jak użycie odbicia.

Jednakże, jeśli odbicie jest dla Ciebie opcją, możesz to zrobić.

public static void main(String[] args) {
    System.out.println("please enter a password");
    // don't actually do this, this is an example only.
    Scanner in = new Scanner(System.in);
    String password = in.nextLine();
    usePassword(password);

    clearString(password);

    System.out.println("password: '" + password + "'");
}

private static void usePassword(String password) {

}

private static void clearString(String password) {
    try {
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        char[] chars = (char[]) value.get(password);
        Arrays.fill(chars, '*');
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

When run

please enter a password
hello world
password: '***********'

Uwaga: jeśli łańcuch znaków [] został skopiowany jako część cyklu GC, istnieje szansa, że poprzednia kopia jest gdzieś w pamięci.

Ta stara Kopia nie pojawi się w zrzut sterty, ale jeśli masz bezpośredni dostęp do surowej pamięci procesu, możesz ją zobaczyć. Ogólnie należy unikać kogokolwiek mając taki dostęp.

 42
Author: Peter Lawrey,
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
2015-07-08 09:34:03

Edit: Wracając do tej odpowiedzi po roku badań nad bezpieczeństwem, zdaję sobie sprawę, że jest to raczej niefortunna sugestia, że kiedykolwiek porównałbyś hasła ze zwykłym tekstem. Proszę nie. Użyj bezpiecznego jednokierunkowego hasha z solą i rozsądną liczbą iteracji . Rozważ korzystanie z biblioteki: trudno jest to zrobić!

Oryginalna odpowiedź: a co z tym, że String.equals () używa oceny zwarcia i dlatego jest podatny na atak czasowy? Może to być mało prawdopodobne, ale można teoretycznie porównać hasło w celu ustalenia prawidłowej kolejności znaków.

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        // Quits here if Strings are different lengths.
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            // Quits here at first different character.
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

Więcej zasobów na temat ataków czasowych:

 34
Author: Graph Theory,
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:26:29

Są to wszystkie powody, należy wybrać char [] array zamiast String dla hasła.

1. ponieważ ciągi znaków są niezmienne w Javie, jeśli zapiszesz hasło jako zwykły tekst, będzie ono dostępne w pamięci do czasu wyczyszczenia go przez Garbage collector, a ponieważ ciągi znaków są używane w Puli ciągów do wielokrotnego użytku, istnieje duża szansa, że pozostanie w pamięci przez długi czas, co stanowi zagrożenie dla bezpieczeństwa. Ponieważ każdy kto ma dostęp do zrzutu pamięci może znaleźć hasło w czystym tekście i to kolejny powód, dla którego zawsze powinieneś używać zaszyfrowanego hasła niż zwykłego tekstu. Ponieważ ciągi są niezmienne, nie ma możliwości zmiany zawartości ciągów, ponieważ każda zmiana spowoduje powstanie nowego ciągu, podczas gdy jeśli znak [] nadal możesz ustawić wszystkie jego elementy jako puste lub zerowe. Tak więc przechowywanie hasła w tablicy znaków wyraźnie zmniejsza ryzyko kradzieży hasła.

2. sama Java zaleca użycie metody getPassword() jpasswordfield która zwraca znak [] i przestarzałą metodę getText (), która zwraca hasło w jasnym tekście z podaniem przyczyny bezpieczeństwa. Dobrze jest stosować się do rad zespołu Java i stosować się do standardu, a nie przeciw niemu.

3. W przypadku String zawsze istnieje ryzyko wydrukowania zwykłego tekstu w pliku dziennika lub konsoli, ale jeśli użyjesz tablicy, nie wydrukujesz zawartości tablicy zamiast jej lokalizacji w pamięci. choć nie jest to prawdziwy powód, ale nadal ma sens.

    String strPassword="Unknown";
    char[] charPassword= new char[]{'U','n','k','w','o','n'};
    System.out.println("String password: " + strPassword);
    System.out.println("Character password: " + charPassword);

    String password: Unknown
    Character password: [C@110b053

Odniesienie od: http://javarevisited.blogspot.com/2012/03/why-character-array-is-better-than.html Mam nadzieję, że to pomoże.

 34
Author: Human Being,
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-11-04 08:13:42

Nie ma nic, co macierz char daje vs String, chyba że wyczyścisz to ręcznie po użyciu, a ja nie widziałem, żeby ktoś tak robił. Więc dla mnie preferencja char[] vs String jest trochę przesadzona.

Spójrz na powszechnie używanąSpring Security library tutaj i zadaj sobie pytanie - czy Spring Security guys są niekompetentni, czy hasła char [] po prostu nie mają większego sensu. Kiedy jakiś paskudny haker chwyta zrzuty pamięci Twojego RAM-a, upewnij się, że dostanie wszystkie hasła, nawet jeśli używasz wyrafinowanych sposobów ich ukrywania.

Jednak Java zmienia się cały czas, a niektóre przerażające funkcje, takie jak Funkcja deduplikacji łańcuchów w Javie 8 mogą internować Obiekty łańcuchowe bez Twojej wiedzy. Ale to inna rozmowa.

 31
Author: Oleg Mikheev,
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:18:26

Ciągi znaków są niezmienne i nie mogą być zmieniane po ich utworzeniu. Utworzenie hasła jako ciąg znaków spowoduje pozostawienie bezpańskich odniesień do hasła na stercie lub w Puli ciągów. Teraz, jeśli ktoś zrobi zrzut sterty procesu Javy i dokładnie przeskanuje, może być w stanie odgadnąć hasła. Oczywiście te nieużywane ciągi będą zbierane śmieci, ale to zależy od tego, kiedy GC zacznie działać.

Po drugiej stronie char [] są mutowalne zaraz po uwierzytelnieniu gotowe możesz nadpisać je dowolnym znakiem, takim jak wszystkie M lub ukośniki. Teraz nawet jeśli ktoś zrobi zrzut sterty, może nie być w stanie uzyskać haseł, które nie są obecnie używane. Daje to większą kontrolę w takim sensie, jak czyszczenie zawartości obiektu samemu lub czekanie na to, aż GC to zrobi.

 28
Author: Geek,
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
2015-07-28 10:46:40

Krótka i prosta odpowiedź brzmiałaby, ponieważ {[0] } jest zmienna, podczas gdy String obiekty nie są.

Strings w Javie są obiektami niezmiennymi. Dlatego nie mogą być modyfikowane po utworzeniu, a zatem jedynym sposobem, aby ich zawartość została usunięta z pamięci, jest ich zbieranie śmieci. Nastąpi to dopiero wtedy, gdy pamięć zwolniona przez obiekt zostanie nadpisana, a dane znikną.

Teraz Garbage collection w Javie nie zdarza się w żadnym interwał. String może więc utrzymywać się w pamięci przez długi czas, a jeśli proces ulegnie awarii w tym czasie, zawartość łańcucha może skończyć się w zrzutu pamięci lub jakimś dzienniku.

Za pomocą tablicy znaków Możesz odczytać hasło, jak najszybciej zakończyć pracę z nim, a następnie natychmiast zmienić zawartość.

 16
Author: Pritam Banerjee,
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-01-05 23:40:12

1) ponieważ ciągi znaków są niezmienne w Javie, jeśli hasło jest zapisywane jako zwykły tekst, będzie ono dostępne w pamięci do czasu wyczyszczenia go przez Garbage collector, a ponieważ ciąg znaków jest używany w Puli ciągów do wielokrotnego użytku, istnieje duża szansa, że pozostanie w pamięci przez długi czas, co stanowi zagrożenie dla bezpieczeństwa. Ponieważ każdy, kto ma dostęp do zrzutu pamięci, może znaleźć hasło w czystym tekście i to kolejny powód, dla którego zawsze powinieneś używać zaszyfrowanego hasła niż zwykłego tekstu. Od Ciągi są niezmienne, nie ma możliwości zmiany zawartości ciągów, ponieważ każda zmiana spowoduje powstanie nowego ciągu, podczas gdy jeśli znak [] nadal możesz ustawić wszystkie jego elementy jako puste lub zerowe. Przechowywanie hasła w tablicy znaków zmniejsza ryzyko kradzieży hasła.

2) sama Java zaleca użycie metody getPassword() jpasswordfield, która zwraca znak[] i przestarzałą metodę getText (), która zwraca hasło w jasnym tekście z podaniem przyczyny bezpieczeństwa. Dobrze jest podążać za porady zespołu Java i przestrzeganie standardu, a nie przeciw niemu.

 14
Author: Neeraj Gahlawat,
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-01-08 20:42:18

String w Javie jest niezmienny. Więc za każdym razem, gdy łańcuch jest tworzony, pozostanie w pamięci, dopóki nie zostanie pobrany śmieci. Więc każdy, kto ma dostęp do pamięci może odczytać wartość ciągu.
Jeśli wartość łańcucha zostanie zmodyfikowana, to w końcu utworzy on nowy łańcuch. Tak więc zarówno oryginalna wartość, jak i zmodyfikowana wartość pozostają w pamięci, dopóki nie zostaną pobrane śmieci.

Za pomocą tablicy znaków zawartość tablicy może być modyfikowana lub kasowana po hasło jest serwowane. Oryginalna zawartość tablicy nie zostanie znaleziona w pamięci po jej zmodyfikowaniu, a nawet przed rozpoczęciem zbierania śmieci.

Ze względu na bezpieczeństwo lepiej jest przechowywać hasło jako tablicę znaków.

 11
Author: Saathvik,
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-07-28 06:33:06

Ciąg jest niezmienny i trafia do puli ciągów. Po zapisaniu nie można go nadpisać.

char[] jest tablicą, którą należy nadpisać po użyciu hasła i tak powinno się to zrobić:

char[] passw = request.getPassword().toCharArray()
if (comparePasswords(dbPassword, passw) {
 allowUser = true;
 cleanPassword(passw);
 cleanPassword(dbPassword);
 passw=null;
}

private static void cleanPassword (char[] pass) {
 for (char ch: pass) {
  ch = null;
 }
}

Jednym ze scenariuszy, w którym atakujący mógłby go użyć, jest crashdump - gdy JVM ulegnie awarii i wygeneruje zrzut pamięci - będziesz mógł zobaczyć hasło.

To niekoniecznie złośliwy zewnętrzny atakujący. Może to być użytkownik wsparcia, który ma dostęp do serwera w celach monitorowania. Mógłby zajrzeć do crashdump i znaleźć hasła.

 10
Author: ACV,
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-04-25 22:39:55