Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make java.io.BufferedOutputStream secured for memory scraper for sensitive card data?

Tags:

java

security

cxf

During a PA-DSS audit process it was found credit card number in our server side code (process memory dump) after running a credit card payment transaction.

I have tried initially just invoke JVM garbage collector at the end of the payment transaction since our variables were local to solve this problem. But there is still a single instance referring to a credit card (CC) in the memory dump. This CC string (actually it was a byte[]) was referenced by SOAP CXF client object that was using internally sun.net.www.protocol.https.HttpsClient that was finally using BufferedOutputStream object.

Looking at code for BufferedOutputStream I have noticed the private flushBuffer() method was just setting the count variable to zero and not resetting the internal byte[] array.

No problem in this code for regular app (just reset count variable is simpler and efficient) but this raised a flag in our secure audit process so my alternative was to create a custom java.io.BufferedOutputStream that it would reset to zero this byte array and then I would need to add this file in the tomcat boot classpath.

   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;
     }
   }

This actually worked and I could not find the CC data in the memory dump anymore but I don't feel this is the correct solution (custom change of a java core class).

Any suggestion how I could address this problem in a different way (w/o having to change any library code) ?

like image 562
amboni Avatar asked Jul 18 '16 19:07

amboni


1 Answers

Java allows you to extend libraries without "having to change any library code". You can extend BufferedOutputStream to make SecureBufferedOutputStream, which will zero the contents of the buffer after a flush and before garbage collection (in case your JVM implementation doesn't already zero garbage collected memory).

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);
    }
}
like image 178
rocketblast Avatar answered Oct 12 '22 22:10

rocketblast