V5333. OWASP. Possible insecure deserialization vulnerability. Potentially tainted data is used to create an object during deserialization.
The analyzer has detected the use of untrusted external data for object deserialization via standard Java mechanisms. This may expose the application to vulnerabilities.
Attacks related to external data deserialization can be categorized under the OWASP Top Ten Application Security Risks:
External data deserialization attacks can be exploited in different ways:
- Data spoofing in deserialized objects. This could lead to granting unauthorized access to a specific user or to injecting an invalid value into an object field.
- Remote code execution. This could include executing malicious OS commands, disclosing credentials, etc.
To minimize the likelihood of these issues, it is recommended to restrict users from sending data to the application for deserialization. If it is required, make sure to follow these tips:
- Use secure libraries for serialization or deserialization (the list is attached below).
- Verify external data.
When using the standard Java deserialization interface, verifying the type of the object being deserialized can protect against potential problems. Note that this must be completed before the object is restored.
The example of the insecure configuration:
public void notSecure(HttpServletRequest req,
HttpServletResponse res) throws .... {
ServletInputStream servletIS = req.getInputStream();
ObjectInputStream objectIS = new ObjectInputStream(servletIS); // <=
Object object = objectIS.readObject();
}
The example of the checked configuration:
class SecureObjectInputStream extends ObjectInputStream {
public SecureObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass osc) throws .... {
List<String> allowedClasses = new ArrayList<>();
allowedClasses.add(AllowedClass1.class.getName());
allowedClasses.add(AllowedClass2.class.getName());
if (!allowedClasses.contains(osc.getName())) {
throw new InvalidClassException("Unauthorized deserialization",
osc.getName());
}
return super.resolveClass(osc);
}
}
....
public void withCheck(HttpServletRequest req,
HttpServletResponse res) throws .... {
ServletInputStream servletIS = req.getInputStream();
ObjectInputStream objectIS = new SecureObjectInputStream(servletIS);
Object object = objectIS.readObject();
}
In the fixed example, the SecureObjectInputStream
class is created as a subclass of the ObjectInputStream
. It overrides the resolveClass
method and checks check what object type is being deserialized. This method is executed before the object is deserialized. If the object is not in the deserialization list, an exception is thrown. This prevents the deserialization of the insecure object whose internal data could compromise the application.
Additional links:
- OWASP. Deserialization Cheat Sheet.
This diagnostic is classified as:
|