Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-4066

Look-ahead deserialization or filtering should be used

    XMLWordPrintable

    Details

    • Message:
      Either use a look-ahead "ObjectInputStream" or incorporate an "ObjectInputFilter" into this deserialization.
    • Highlighting:
      Hide

      new ObjectInputStream

      Show
      new ObjectInputStream
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Targeted languages:
      Java
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      20min
    • Analysis Scope:
      Main Sources, Test Sources
    • CERT:
      SER12-J.
    • OWASP:
      A8

      Description

      Deserialization takes a stream of bits and turns it into an object. If the stream contains the type of object you expect, all is well. But if you're deserializing untrusted input, and an attacker has inserted some other type of object, you're in trouble. Why? There are a few different attack scenarios, but one widely-documented one goes like this: Deserialization first instantiates an Object, then uses the readObject method to populate it. If the attacker has overridden readObject then he is entirely in control of what code executes during that process. It is only after readObject has completed that your newly-minted Object can be cast to the type you expected. A ClassCastException or ClassNotFoundException will be thrown, but at that point it's too late.

      To prevent this, you should either use look-ahead deserialization (pre-Java 9) or filtering to make sure you're dealing with the correct type of object before you act on it.

      Several third-party libraries offer look-ahead deserialization, including:

      • ikkisoft's SerialKiller
      • Apache Commons Class IO's ValidatingObjectInputStream
      • contrast-rO0's SafeObjectInputStream

      Note that it is possible to set a deserialization filter at the level of the JVM, but relying on that requires that your environment be configured perfectly. Every time. Additionally, such a filter may have unwanted impacts on other applications in the environment. On the other hand, setting a filter as close as possible to the deserialization that uses it allows you to specify a very narrow, focused filter.

      Noncompliant Code Example

      FileInputStream in = new FileInputStream("obj");
      ObjectInputStream ois = new ObjectInputStream(in);  // Noncompliant
      Foo reconstitutedFoo = (foo)ois.readObject();
      

      Compliant Solution

      FileInputStream in = new FileInputStream("obj");
      ObjectInputStream ois = new SerialKiller(is, "/etc/serialkiller.conf");
      String msg = (String) ois.readObject();
      

      Or for Java 9

      class MyFilter implements ObjectInputFilter {
        @Override
        public Status checkInput(Filterinfo filterInfo) { ...}
      }
      
      //...
          FileInputStream in = new FileInputStream("obj");
          ObjectInputStream ois = new ObjectInputStream(in); 
          ois.setObjectInputFilter(new MyFilter());  // 
          Foo reconstitutedFoo = (foo)ois.readObject();
      

      See

      • CERT, SER12-J. - Prevent deserialization of untrusted data
      • OWASP Top 10 2017 Category A8 - Insecure Deserialization

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              ann.campbell.2 Ann Campbell
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: