如何使java.io.BufferedOutputStream为敏感卡数据的内存刮刀安全?

时间:2016-07-18 19:53:55

标签: java security cxf

在PA-DSS审核过程中,在运行信用卡付款交易后,我们在服务器端代码(进程内存转储)中发现了信用卡号。

我最初尝试过在支付交易结束时调用JVM垃圾收集器,因为我们的变量是本地的,以解决这个问题。但是仍有一个实例指的是内存转储中的信用卡(CC)。这个CC字符串(实际上是一个byte [])是由内部使用sun.net.www.protocol.https.HttpsClient的SOAP CXF客户端对象引用的,最终使用的是BufferedOutputStream对象。

查看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核心类)。

有任何建议如何以不同的方式解决此问题(无需更改任何库代码)?

1 个答案:

答案 0 :(得分:4)

Java允许您扩展库而不需要更改任何库代码&#34;。您可以扩展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);
    }
}