63 lines
1.8 KiB
Plaintext
63 lines
1.8 KiB
Plaintext
=== How to fix it in Java SE
|
|
|
|
The following code is vulnerable to deserialization attacks because it
|
|
deserializes HTTP data without validating it first.
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
public class RequestProcessor {
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
|
ServletInputStream servletIS = request.getInputStream();
|
|
ObjectInputStream objectIS = new ObjectInputStream(servletIS);
|
|
Object input = objectIS.readObject();
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
public class SecureObjectInputStream extends ObjectInputStream {
|
|
|
|
@Override
|
|
protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
|
|
|
|
List<String> approvedClasses = new ArrayList<String>();
|
|
approvedClasses.add(AllowedClass1.class.getName());
|
|
approvedClasses.add(AllowedClass2.class.getName());
|
|
|
|
if (!approvedClasses.contains(osc.getName())) {
|
|
throw new InvalidClassException("Unauthorized deserialization", osc.getName());
|
|
}
|
|
|
|
return super.resolveClass(osc);
|
|
}
|
|
}
|
|
|
|
public class RequestProcessor {
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
|
|
ServletInputStream servletIS = request.getInputStream();
|
|
ObjectInputStream objectIS = new SecureObjectInputStream(servletIS);
|
|
Object input = objectIS.readObject();
|
|
}
|
|
}
|
|
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/introduction.adoc[]
|
|
|
|
include::../../common/fix/safer-serialization.adoc[]
|
|
|
|
include::../../common/fix/integrity-check.adoc[]
|
|
|
|
include::../../common/fix/pre-approved-list.adoc[]
|
|
|
|
In the previous example, the pre-approved list uses class names to validate the
|
|
deserialized class.
|
|
|