[Advanced-java] Sensitive Data -> StringgetParameter(String ) Alternative

Carlo carlo.ravagli at extropia.com
Sat May 3 04:56:37 2003


In addition to Martin's comments you must also consider
what is happening in the computer's physical memory and
more importantly what is happening to the data when the
HTTPS request is forwarded to the servlet engine

The user's HTTPS request is probably going to hit
a web server before being forwarded to the servlet
engine. The web server (using SSL libs) is going to
have to decrypt the HTTPS request. At this point
the unencrypted sensitive data is probably going to
be in memory somewhere. The memory is probably
allocated on the heap and eventually freed. When the
memory is freed the computer does necessarily
"clear" the data by replacing it with all zeros. It is only
destroyed when memory is allocated in the same
address space and new data overwrites the old data.
(Note: this is also true for the JVM. Just because an
object is garbage collected does not mean it's
associated data is "cleared" in physical memory).

For the same bit of data, memory will probably be allocated
and written to and then freed but not "cleared" a
couple of times before it even hits the servlet engine.

However, lets ignore this issue for the moment and assume
that our hacker is not going to scan the physical
memory because there is a much easier way to get to
your sensitive data.

Continuing with our HTTPS request, after it has
been decrypted by the web server it becomes
a regular HTTP unencrypted request which eventually
needs to forwarded to the servlet engine. This is
normally done over a regular TCP socket (even
when the servlet engine resides on the same box).
Some servlet engines provide a plug-in for
the web server so the HTTP request data is send over
the socket using a more efficient protocol but
most just sent plain old HTTP. There is nothing to
stop a hacker sniffing the data as it is passed over
the socket from the web server to the servlet engine.

What we have had to do in the past is actually encrypt
the sensitive data on the browser with an applet (in addition
to HTTPS). Here is the process:

1) Applet encrypts sensitive data and then base64 encodes it.
If you base64 encode it after encryption you don't need to worry
about multipart form data.
2) The encoded encrypted sensitive data is sent from the browser
using HTTPS by applet (or directly by the browser if you can
use javascript). The encrypted encoded data is encrypted a
second time in the HTTPS request.
3) The web server decrypts the HTTPS request.
The sensitive data is still encrypted and base64 encoded.
4) HTTP request is forwarded to servlet engine over the
TCP socket.
5) Only when the sensitive data is required is
it decoded and decrypted. This may occur in the servlet
engine or more appropriately in another JVM on a more
secure server after an RMI call.

Many banks use this technique to protect user passwords/pins
within their on-line banking applications.

Hope this helps,

Carlo.

----- Original Message ----- 
From: "Martin Cooper" <martin.cooper@tumbleweed.com>
To: <nikolaos@solmar.ca>; "Jukka Sundberg" <jukka@citrus.fi>
Cc: <advanced-java@lists.xcf.berkeley.edu>
Sent: Saturday, May 03, 2003 4:06 AM
Subject: RE: [Advanced-java] Sensitive Data -> StringgetParameter(String )
Alternative


>
>
> > -----Original Message-----
> > From: Nikolaos Giannopoulos [mailto:nikolaos@solmar.ca]
> > Sent: Friday, May 02, 2003 9:12 AM
> > To: Jukka Sundberg
> > Cc: advanced-java@lists.xcf.berkeley.edu
> > Subject: RE: [Advanced-java] Sensitive Data ->
> > StringgetParameter(String
> > )Alternative
> >
> >
>
> <snip/>
>
> > Earnest Friedman in an offline discussion suggested doing the
> > following:
> >
> > > You could call getParameter().toCharArray(), and use the char[]; the
> > > String then would be collectible immediately, right?
> >
> > Which is probably the best work around for the problem at hand.
>
> I don't believe this will do what you want. When the container parses the
> request, it's almost certainly going to build up a map of name/value pairs
> for the parameters, one of which will correspond to your credit card
number.
> Using toCharArray() will ensure that *your* code doesn't have the card
> number in a string, but the container will still have it.
>
> I think the only way you can get around this is to use a POST that uses
the
> multipart/form-data encoding, and then parse the entire request yourself
> after calling request.getInputStream().
>
> Actually, the latest version (meaning HEAD in CVS, not yet released) of
> Jakarta Commons FileUpload would probably help you a lot with this. It
uses
> a factory to create each item as it parses the request. You could quite
> easily create your own factory that avoids storing the data as a string,
and
> then rely on FileUpload to do the hard work for you.
>
> It's conceivable that you could get away with parsing a regular POST
> yourself, but that would depend entirely on exactly when your container
> decides to parse the request. That being the case, it certainly wouldn't
be
> portable, and I wouldn't recommend this approach.
>
> --
> Martin Cooper
>
>
> >
> > If anyone has any other input or comments please feel free to
> > jump in ;-)
> >
> > Thanks,
> >
> > --Nikolaos
> >
> >
> > _______________________________________________
> > Advanced-java mailing list
> > Advanced-java@lists.xcf.berkeley.edu
> > http://lists.xcf.berkeley.edu/mailman/listinfo/advanced-java
> >
>
> _______________________________________________
> Advanced-java mailing list
> Advanced-java@lists.xcf.berkeley.edu
> http://lists.xcf.berkeley.edu/mailman/listinfo/advanced-java
>
>