2016-07-18 14 views
5

Podczas procesu audytu PA-DSS został znaleziony numer karty kredytowej w naszym kodzie po stronie serwera (zrzut pamięci procesu) po uruchomieniu transakcji płatności kartą kredytową.Jak zabezpieczyć skrytkę pamięci dla java.io.BufferedOutputStream dla wrażliwych danych karty?

Próbowałem początkowo po prostu wywołać narzędzie do usuwania śmieci JVM na końcu transakcji płatniczej, ponieważ nasze zmienne były lokalne, aby rozwiązać ten problem. Ale nadal istnieje jedna instancja odwołująca się do karty kredytowej (CC) w zrzucie pamięci. Ten ciąg znaków CC (w rzeczywistości był to bajt []) został odwołany przez obiekt klienta CXF protokołu SOAP, który korzystał wewnętrznie z sun.net.www.protocol.https.HttpsClient, który ostatecznie używał obiektu BufferedOutputStream.

Patrząc na kod dla BufferedOutputStream Zauważyłem, że prywatna metoda flushBuffer() właśnie ustawiała zmienną count na zero i nie resetowała wewnętrznej tablicy byte [].

Nie ma problemu w tym kodzie dla zwykłej aplikacji (wystarczy zresetować zmienną licznika jest prostsza i wydajniejsza), ale podniosło to flagę w naszym procesie bezpiecznego audytu, więc moją alternatywą było utworzenie niestandardowego java.io.BufferedOutputStream, który zostałby zresetowany do Zeruj tę tablicę bajtów, a następnie będę musiał dodać ten plik w ścieżce rozruchowej tomcat.

private void flushBuffer() throws IOException { 
    if (count > 0) { 
     out.write(buf, 0, count); 

     //NEW - Custom code to reset buffer 
     for (int i = 0; i < count; i++) { 
      buf[i] = 0; 
     } 
     //End custom code 

     count = 0; 
    } 
    } 

To rzeczywiście pracował i nie mogłem znaleźć dane CC w pamięci zrzucić, ale już nie czuję to jest poprawne rozwiązanie (zwyczaj zmiany rdzenia klasy Java).

Jakieś sugestie, w jaki sposób mogę rozwiązać ten problem w inny sposób (bez konieczności zmiany kodu biblioteki)?

+0

Czy klient SOAP jest buforowany w jakiś sposób? A może to połączenie, z którego korzysta? –

+0

Jestem zaskoczony, że to jedyny przypadek, jaki znalazłeś. Zasadniczo zrzuty JVM nie są zaskakująco bezpieczne. – EJP

+0

Sprawdziłem w Eclipse Memory Analyzer i pamięci podręcznej klasy te wrażliwe dane to sun.security.ssl.SSLSocketImpl (wewnątrz handshakeListeners pola). Ale nie mam żadnego bezpośredniego odniesienia do tego klienta mydła ani tego połączenia. – amboni

Odpowiedz

4

Java pozwala rozszerzać biblioteki bez "konieczności zmieniania kodu biblioteki". Można rozszerzyć BufferedOutputStream, aby uzyskać SecureBufferedOutputStream, co spowoduje zerowanie zawartości bufora po spłukaniu i przed czyszczeniem pamięci (w przypadku, gdy implementacja maszyny JVM nie wyzeruje pamięci zebranych śmieci).

import java.io.BufferedOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.Arrays; 

public class SecureBufferedOutputStream extends BufferedOutputStream { 

    public SecureBufferedOutputStream(OutputStream out) { 
     super(out); 
    } 

    public SecureBufferedOutputStream(OutputStream out, int size) { 
     super(out, size); 
    } 

    @Override 
    public synchronized void flush() throws IOException { 
     super.flush(); 
     Arrays.fill(buf, (byte) 0); 
    } 

    @Override 
    protected void finalize() throws Throwable { 
     super.finalize(); 
     Arrays.fill(buf, (byte) 0); 
    } 
} 
+0

Dzięki za odpowiedź rocketblast, ale jak powiedziałem w pytaniu, problem był w innej bibliotece Java (CXF), który używa BufferedOutputStream. Musiałbym zmienić wszystkie odpowiednie klasy CXF, aby użyć tego nowego bezpiecznego bufora. Tak więc nadal potrzebowałbym zmienić tę bibliotekę apache. – amboni

Powiązane problemy