[Cryptography] Heartbleed and fundamental crypto programming practices

Kevin W. Wall kevin.w.wall at gmail.com
Sat Apr 12 16:43:35 EDT 2014


On Fri, Apr 11, 2014 at 9:57 AM, ianG <iang at iang.org> wrote:
> On 10/04/2014 07:15 am, Jerry Leichter wrote:
>
>> ...Also, since String's are immutable in Java, you have the
>> problem that even if you know you've got sensitive data you
>> no longer need stored in a String ... there's   nothing you can
>> do to get rid of it.)
>
> That problem - exactly, does anyone know a solution in Java
> to cleansing Strings?

Well, this is a common myth that Java Strings are immutable.

Strings in Java are not really immutable unless one is using a
SecurityManager and enforcing that this by restricting manipulation
via reflection via an appropriate security policy. The use of *any*
SecurityManager is extremely rare [except in applets] and it's
presence can be tested for. Furthermore and those places that do
use a SecurityManager with a custom security policy rarely restrict
reflection, at least completely. And of course, if you are doing this
in your own application, presumably you would have some say as to
what security policy was needed.

Jeff Williams, of Aspect Security, is the first one that I've seen
who publicly discussed this (at Black Hat USA 2009; see
<http://www.blackhat.com/presentations/bh-usa-09/WILLIAMS/BHUSA09-Williams-EnterpriseJavaRootkits-PAPER.pdf>
for details).

Here's a code snippet from that paper that allows you to
change Java Strings...even Strings that are declared 'final'.
And with a bit more work, one could even extend this technique
to find and alter Strings that are declared 'private' within a
given class. You would just have to pass in an Object and the
name of the field you wanted to alter. (Left as an exercise for the
reader.)

    public static void changeString(String original, String replacement)
    {
        try {
            Field value = String.class.getDeclaredField("value");
            value.setAccessible(true);
            value.set(original, replacement.toCharArray());
            Field count = String.class.getDeclaredField("count");
            count.setAccessible(true);
            count.set(original, replacement.length());
        } catch (Exception ex) {
            ; // ignore
        }
    }

Or course, reflection is relatively expensive so if you wanted to
overwrite passwords, etc. in a legitimate context, the first thing
is to convert the to byte[] arrays (or alternately char[]) as soon
as possible rather than continuously passing them as Strings.

By the way, if you are responsible for doing secure code reviews
in Java and your threat model includes developers as a legitimate
insider threat than Jeff's paper is a must-read IMO.

-kevin
-- 
Blog: http://off-the-wall-security.blogspot.com/
NSA: All your crypto bit are belong to us.


More information about the cryptography mailing list