Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2021.1

If a class implements Externalizable, public readExternal and writeExternal methods have to be provided. Unfortunately, these methods are public and thus Classes that implement the Externalizable interface must provide the readExternal() and writeExternal() methods. These methods have package-private or public access, and so they can be called by hostile code which can potentially trusted and untrusted code alike. Consequently, programs must ensure that these methods execute only when intended and that they cannot overwrite the internal state of the object through multiple callsobjects at arbitrary points during program execution.

Noncompliant Code Example

This noncompliant code example allows anyone any caller to reset the value of the object due to the public access modifier of at any time because the readExternal method.() method is necessarily declared to be public and lacks protection against hostile callers:

Code Block
bgColor#FFcccc

public void readExternal(ObjectInput in) 
                         throws IOException, ClassNotFoundException {
   // readRead instance fields
   this.name = (String) in.readObject();
   this.UID = in.readInt();
   // ...
}

Compliant Solution

This thread-safe solution allows the first caller to set an initialized flag following which, the instance fields are populatedcompliant solution protects against multiple initialization through the use of a Boolean flag that is set after the instance fields have been populated. It also protects against race conditions by synchronizing on a private lock object (see LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code).

Code Block
bgColor#ccccff
private final Object lock = new Object();
private boolean initialized = false;

public synchronized void readExternal(ObjectInput in)
                         throws IOException, ClassNotFoundException {
  synchronized (lock) {
    if (!initialized) {
      // readRead instance fields
      this.name = (String) in.readObject();
      this.UID = in.readInt();
      // ...  
      initialized = true;
    } else {
      throw new IllegalStateException();
    }
  }
}

Note that this compliant solution is inadequate to protect sensitive data.

Risk Assessment

Failure to prevent the overwriting of an externalizable object can corrupt the state of the object.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SER11-J

Low

Probable

Low

P6

L2

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.SER11.IRXAvoid re-initializing fields in the 'readExternal()' method of 'Externalizable' classes

Bibliography

[API 2014]


[Sun 2006]

Serialization Specification, A.7, Preventing Overwriting of Externalizable Objects


...

Image Added Image Added Image Added