23

Hi I'm getting the violation as below:

Malicious code vulnerability - May expose internal representation by returning reference to mutable object

in my code i wrote like this

public String[] chkBox() {
    return chkBox;
}

How we can solve it.

atavakoli
  • 1,209
  • 2
  • 12
  • 18
jayavardhan
  • 587
  • 5
  • 9
  • 19

2 Answers2

41

As the error message states, you're returning internal state (chkBox is - most likely - part of the internal state of an object even though you're not showing its definition)

This can cause problems if you - for example - do

String[] box = obj.chkBox();
box[0] = null;

Since an array object, as all Java objects, is passed by reference, this will change the original array stored inside your object as well.

What you most likely want to do to fix this is a simple

return (String[])chkBox.clone();

which returns a copy of the array instead of the actual array.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • 1
    in above solution we will end up creating a new String[] object everytime we access it through clone().I just need to compare (and not end up creating a new object) does anybody hav a better solution? – Raj Trivedi Jun 30 '15 at 12:30
  • 3
    I don't understand how this is useful other than to defeat Findbugs. The copied array still has the references to the Strings that comprise the state of obj. – David Feb 29 '16 at 14:05
  • Also, if chkBox was getChkBox, I would expect to get the reference to the underlying object. Then the getter would need to return an reference to an abstract class of some sort, no? – David Feb 29 '16 at 14:06
  • 2
    That makes sense Joachim, thanks. I'm mulling this problem right this second. I have a class that someone else wrote that returns DomainSpecificClass[].clone() in getters. – David Feb 29 '16 at 14:08
12

Let's suppose the following:

  1. Your class does something that matters from a security or privacy perspective, and that the state of chkbox is somehow used in the classes implementation of its privacy / security mechanisms.

  2. The chkBox() method can be called by some code that is not trusted.

Now consider this code:

// ... in an untrusted method ...

Foo foo = ... 
String[] mwahaha = foo.chkBox();
mwahaha[0] = "Gotcha!"; // ... this changes the effective state of `Foo`

By returning a reference to the actual array that represents the chkbox, you are allowing code external to the Foo class to reach in and change its state.

This is bad from a design perspective (it is called a "leaky abstraction"). However, if this class is used in a context where there may also be untrusted code, this (the chkBox() method) is a potential security hole. That is what the violation message is telling you.

(Of course, the code checker has no way of knowing if this particular class is really security critical. That's for you to understand. What it is actually saying to you is "Hey! Look here! This is suspicious!")


The fix depends on whether this code (or indeed the entire library or application) is security critical ... or code be security critical in some future deployment. If this is a false alarm, you could just suppress the violation; i.e. mark it so that will be ignored by the checker. If this is a real issue (or could become a real issue), then either return a copy of the array:

    return (String[]) chkBox.clone();

But clearly, there is a performance cost in cloning the array each time you call chkBox. Alternatively, you could modify the chkBox method to return a selected element of the array:

    public String chkBox(int i) {
       return chkBox[i];
    }

In this case, I suspect that the alternative approach will be better ... though it depends on how the method is currently used.

Niels Bech Nielsen
  • 4,777
  • 1
  • 21
  • 44
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    I still wonder why sonar is reporting this issue for arrays only, and not, e.g., for lists or any other kind of mutable data structure. Is there more to it, maybe due to the way arrays are stored in memory? – tobias_k Oct 13 '14 at 14:59
  • *"Is there more to it, maybe due to the way arrays are stored in memory?"* - As far as I'm aware, no. – Stephen C Oct 13 '14 at 22:29
  • 1
    The real difference is that with an array it is impossible to prevent someone with the array reference from changing the contents. With object types, access it mediated by the object API (if the API is properly chosen implemented) which makes it hard to distinguish between safe and unsafe usages. (If bug checker "cried wolf" too often, it wouldn't be used.) – Stephen C Oct 13 '14 at 22:32
  • @Stephen C, if I have a chance, can I change the type from Array to ArrayList to avoid exposing the information? – Brooklyn99 Apr 07 '21 at 14:36
  • Think about it. If you return an `ArrayList`, then the caller can perform mutation operations on it ... and your abstraction is still leaky. Returning an unmodifiable list would be an improvement ... depending on what is in the list. – Stephen C Apr 07 '21 at 14:41
  • (The problem is not exposing information. If you want to avoid exposing information, don't have a `chkBox` method at all.) – Stephen C Apr 07 '21 at 14:43
  • OK, but when I change the return type of chkBox() to ArrayList, the too(here I am talking abt findbugs) does not flag it as a bug. – Brooklyn99 Apr 07 '21 at 14:45
  • Well, that's because the tool doesn't have a way of *knowing* where the (design) abstraction boundary really lies. (Not even in the array case!) Tools like this work by pattern matching against the code's parse tree to look for code patterns that are *likely* to be a problem. The "returns the value of an array-typed field" pattern matches code that is *usually* a leaky abstraction. But if they flagged every case where some code returned a `Collection` there would be too may false positives. – Stephen C Apr 07 '21 at 14:57