1

In a Java programming book there is a section that details the JVM and memory addresses and location as it pertains to parameters of a class type. As you can see from the console output the initial object is overwritten in memory (potentially unintentionally to the API author). It was explained to me that this can be an unintended software security vulnerability and would be something detected during a manual code review.

Can someone explain in what fashion this vulnerability would be exploited? Would it be in using someone else's API that contains this vulnerability or would it be in exploiting an actual application containing this? Are there any examples (in the news perhaps) of this being done?

Here is how it functions, according to the text:

MainActivity.class:

public class MainActivity {

public static void main(String[] args) {
        ToyClass anObject = new ToyClass("Mr. Cellophane", 0);
        System.out.println(anObject);
        System.out.println("Now we call changer with anObject as an argument");
        ToyClass.changer(anObject);
        System.out.println(anObject);
    }
}

ToyClass

public class ToyClass {
    private String name;
    private int number;

    public ToyClass(String initialName, int initialNumber) {
        name = initialName;
        number = initialNumber;
    }

    public ToyClass() {
        name = "No name yet.";
        number = 0;
    }
    public void set(String newName, int newNumber) {
        name = newName;
        number = newNumber;
    }
    public String toString() {
        return (name +" " + number);
    }
    public static void changer(ToyClass aParameter) {
        aParameter.name = "Hot Shot";
        aParameter.number = 42;
    }
    public boolean equals(ToyClass otherObject) {
        return ((name.equals(otherObject.name)&& (number == otherObject.number) ));
    }
}

Console Output:

Mr. Cellophane 0
Now we call changer with anObject as an argument
Hot Shot 42

Edit: To explain the background a bit more. This example shows how in the JVM memory system two objects are at a different address while the stored parameter is in the same memory location, and is overwritten by the second method. This is the basis of the "vulnerability".

2
  • 1
    Could you explain why you think this may be relevant to security? All of this is happening inside one program, so there is no crossing of any security boundary. Furthermore, I don't even see any surprising behavior here: Java objects are mutable, so changer being able to modify its parameter is expected behavior. Sep 22, 2012 at 12:16
  • @Gilles, there may be different security contexts within one java program because of the Java Sandbox. Sep 23, 2012 at 7:28

3 Answers 3

3

What this example shows is that class instances in Java are mutable: the contents of an instance can change during the lifetime of the instance. This can be surprising for people who have done too much Haskell but is otherwise a quite basic characteristic of Java, which is shared by many programming languages, including C, C++, Javascript, C#, Forth, Pascal...

Immutable instances are convenient for programming, in particular when several developers must collaborate. In Java, the String class is the canonical example of immutable instances: each String instance represents a given string which cannot be changed(*). When you want to modify a string, you call a method such as substring() which does not really modify the string; instead, it creates and return a new String instance, leaving the original string untouched. When you have immutable instances, you can keep them and share them with less precautions.

For instance, suppose that you have a class which represents an authenticated user:

public class AuthenticatedUser {

    private String name;

    public String getName()
    {
        return name;
    }
}

Such an instance keeps the name of the authenticated user in an internal field. The getName() method returns that name -- it can return the same instance that it keeps internally, because String instances are immutable: the caller will not be able to modify it anyway. So no need to build a copy, the public getName() can give the real string right away.

Mutable instances, by contrast, require more care and, often, a lot of copying. Failing to do that can result in subtle bugs, and security vulnerabilities are nothing else then bugs which have come to the attention of an ill-intentioned individual.

Java is a language which has some useful features for making immutable objects: - Its strong types forbid operations which do not follow the type systems (as opposed to, say, C, where everything is just a bunch of bytes and can be accessed as such). - Methods and fields can be tagged with a visibility such as the private above. - Java includes a garbage collector which is the necessary complement for sharing immutable instances across method calls (without automatic memory management, such sharing must include rules for who is responsible for releasing memory, and this rarely works well).

So the point your are describing is not a "Java vulnerability". Rather, it is a common source of bugs (some of which being vulnerabilities) which can be avoided thanks to the tools that Java provides. It would be more appropriate to call it a "C vulnerability, that you need not live with if you develop in Java".


(*) That's not entirely true: string instances can be modified through reflection -- albeit not reliably and in a standard way. Reflective access to private fields is a special permission which unsigned Java applet do not have, so do not worry about this.

2

I don't think the code you posted can specifically be exploited as a vulnerability. What you posted is a reasonable programming practice. That method "changer(ToyClass)" re-assigns the value of the parameter. You can basically do that from anywhere, like the following:

public class WhateverClass {

public static void changer(ToyClass aParameter) {
      aParameter.name = "Anything";
      aParameter.number = 99;
}
}

And so calling

WhateverClass.changer(anObject);

will do the same thing as your code, albeit you need to change the scope of name and number to package and not private. But essentially as I see it, you are just changing the variable from a specific class. Just so happens that method is inside the object in question and is static.

I don't see how someone would exploit that. Would be nice to have someone who knows the VM internals to comment.

1
  • Those were pretty much my thoughts. I can see this as an intentional programming practice but I was told if the programmer is unaware of the mechanics it could be an unintended vulnerability (I think in an api that would be published).
    – KDEx
    Sep 22, 2012 at 14:42
2

This isn't a vulnerability in Java. That's how Java is designed to work.

In some cases it could conceivably be a vulnerability in ToyClass, if the author of this code didn't realize he was providing the ability to change instances -- but in that case, the programmer probably doesn't know Java and shouldn't be writing security-critical code in Java.

Of course, if the programmer does not understand the programming language he/she is programming in, you can certainly end up with horrible vulnerabilities, but that is true of every language. If you want to build secure code, you need to start by understanding your tools!

Bottom line: This is a pretty basic aspect of Java. I don't see anything surprising or particularly hazardous to security here.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .