Details

    • Type: Language-Specification
    • Status: Active
    • Resolution: Unresolved
    • Labels:
      None
    • Impact:
      Unknown 'null' severity
    • Likelihood:
      Unknown 'null' severity

      Description

      User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Deserialization based on data supplied by the user could result in two types of attacks:

      • Remote code execution attacks, where the structure of the serialized data is changed to modify the behavior of the object being unserialized.
      • Parameter tampering attacks, where data is modified to escalate privileges or change for example quantity or price of products.

      The best way to protect against deserialization attacks is probably to challenge the use of the deserialization mechanism in the application. They are cases were the use of deserialization mechanism was not justified and created breaches (CVE-2017-9785).

      If the use of deserialization mechanisms is valid in your context, the problem could be mitigated in any of the following ways:

      • Instead of using a native data interchange format, use a safe, standard format such as untyped JSON or structured data approaches such as Google Protocol Buffers.
      • To ensure integrity is not compromised, add a digital signature (HMAC) to the serialized data that is validated before deserialization (this is only valid if the client doesn't need to modify the serialized data)
      • As a last resort, restrict deserialization to be possible only to specific, whitelisted classes.

      This rule supports: Java native serialization, XMLEncoder and Kryo

      Noncompliant Code Example

      public class RequestProcessor {
        protected void processRequest(HttpServletRequest request) {
          ServletInputStream sis = request.getInputStream();
          ObjectInputStream ois = new ObjectInputStream(sis);
          Object obj = ois.readObject(); // Noncompliant
        }
      }
      

      Compliant Solution

      public class SecureObjectInputStream extends ObjectInputStream {
        // Constructor here
      
        @Override
        protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
          // Only deserialize instances of AllowedClass
          if (!osc.getName().equals(AllowedClass.class.getName())) {
            throw new InvalidClassException("Unauthorized deserialization", osc.getName());
          }
          return super.resolveClass(osc);
        }
      }
      
      public class RequestProcessor {
        protected void processRequest(HttpServletRequest request) {
          ServletInputStream sis = request.getInputStream();
          SecureObjectInputStream sois = new SecureObjectInputStream(sis);
          Object obj = sois.readObject();
        }
      }
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              lars.svensson Lars Svensson (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: