2016-07-18 6 views
5

PA-DSS監査プロセス中、クレジットカード決済トランザクションを実行した後、当社のサーバー側コード(プロセスメモリダンプ)にクレジットカード番号が見つかりました。機密カードデータ用にメモリスクレーパー用にjava.io.BufferedOutputStreamをセキュリティで保護する方法を教えてください。

私はこの問題を解決するために変数がローカルなので、支払いトランザクションの最後にJVMガベージコレクタを呼び出すようにしました。しかし、メモリダンプのクレジットカード(CC)を参照しているインスタンスはまだ1つあります。このCC文字列(実際はバイト[])は、最終的にBufferedOutputStreamオブジェクトを使用していたsun.net.www.protocol.https.HttpsClientを内部的に使用していたSOAP CXFクライアントオブジェクトによって参照されていました。

BufferedOutputStreamのコードを見る私はflushBuffer()メソッドがcount変数をゼロに設定していて、内部のbyte []配列をリセットしていないことに気付きました。

普通のアプリケーションの場合、このコードで問題はありません(リセットカウント変数は単純で効率的です)が、私たちの安全な監査プロセスでフラグを立てて、代替のカスタムjava.io.BufferedOutputStreamを作成しましたこのバイト配列をゼロにしてから、このファイルを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; 
    } 
    } 

これは、実際に働いたと私はもうダンプメモリにCCデータを見つけることができませんでしたが、私はこれが正しい解決策(Javaのコアクラスのカスタム変更)で感じることはありません。

どのように私は別の方法でこの問題に対処することができます(任意のライブラリコードを変更する必要はありません)?

+0

SOAPクライアントが何らかの形でキャッシュされていますか?または、それが使用する接続かもしれませんか? –

+0

私はあなたが見つけた唯一のケースであることに私は驚いています。一般に、JVMダンプは驚くほど安全ではありません。 – EJP

+0

私はEclipse Memory Analyzerを調べました。この機密データをキャッシュするクラスはsun.security.ssl.SSLSocketImplです(フィールドhandshakeListeners内)。しかし、私はこの石鹸クライアントまたはこの接続への直接参照を保持しません。 – amboni

答えて

4

Javaでは、「ライブラリコードを変更することなく」ライブラリを拡張することができます。 BufferedOutputStreamを拡張してSecureBufferedOutputStreamを作成すると、フラッシュ後とガベージコレクションの前にバッファの内容がゼロになります(JVM実装でガベージコレクションされたメモリがゼロになっていない場合)。

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

あなたの答えrocketblastをありがとうが、私の質問では問題が別のJavaライブラリCXF)を使用します。私は、この新しい安全なバッファを使用するために、関連するすべてのCXFクラスを変更する必要があります。だから私はまだこのapacheライブラリを変更する必要があります。 – amboni

関連する問題