Behavioral change in K2 Endpoint Service Types
Issue
K2 identified an issue regarding insecure deserialization that affects all Endpoint SmartObject Service Types. Please read this entire article and apply the fix pack as soon as is practical for your environment.
Change
Removed support for complex objects in endpoint SmartObject Service Types that have properties of type Interface, Abstract Class, or System.Object (Non-Typed types) in the following releases:
- K2 Cloud Update 9 Fix Pack 8
- K2 4.7 March 2018 Cumulative Update Fix Pack 51
- K2 Five (5.0) September 2018 Cumulative Update Fix Pack 18
- K2 Five (5.1) November 2018 Cumulative Update Fix Pack 22
- K2 Five (5.2) May 2019 Cumulative Update Fix Pack 13
- K2 Five (5.3) Fix Pack 18
Affected Service types
The following Service Types are affected by this change:
- Endpoint Assembly Broker (Not available in K2 Cloud)
- Endpoint Web Service Broker
- Endpoint WCF Broker
- OData Broker
- REST Broker
Mitigation
You must upgrade to the latest version/fix pack to mitigate the security issue.
Solution designers can reduce, but not eliminate, the security risk before applying the latest version/fix pack by using the information provided in the Chaining Methods section of the following documentation, and by not exposing any properties to front-ends that require a serialized string as input.
K2 Cloud Update 9 User Guide: https://help.k2.com/onlinehelp/k2cloud/userguide/update_9/default.htm#ServiceBrokers/EndPoints/SmartObject-Serialization-Deserialization.htm
K2 4.7 user guide: http://help.k2.com/onlinehelp/K2blackpearl/UserGuide/4.7/default.htm#ServiceBrokers/EndPoints/SmartObject_Serialization-Deserialization.htm
K2 Five (5.3) user guide: https://help.k2.com/onlinehelp/k2five/userguide/5.3/default.htm#ServiceBrokers/EndPoints/SmartObject-Serialization-Deserialization.htm
Potential errors after applying the mitigation
After applying the fix, solutions may start exhibiting errors if the solutions relied on support for Interface, Abstract Class, and System.Object properties. These errors could differ significantly depending on how the backend service handles these properties when they are empty. The following are some examples of errors that could occur:
- "Object reference not set to an instance of an object"
- "The server was unable to process the request due to an internal error"
- "Unable to deserialize value JObject to jObjectTypeName]" (where ObjectTypeName is the name of the objects being deserialized)
Identifying post-mitigation issues in your environment
Investigate if the fix causes these errors. K2 added additional logging to the hostServer logs that log an error message for an ignored property or when the deserialization process did not result in a properly-typed object. The following messages display in the HostServer logs:
- "Unable to properly deserialize object for broker..." - occurs when the deserialization could not deserialize to the expected type
- "Ignoring property of type..." - occurs when the deserialized object has a property of type Interface, Abstract Class, or System.Object
Note that these error log messages by themselves do not necessarily mean there is an issue, but if combined with other errors it is an indication that it could be the result of the fix.
After applying the fix, type information in a serialized value (used to determine what value type should be deserialized to) is no longer used. This means that complex properties of type Interface, Abstract Class, or System.Object will no longer convert to a specific type and the deserialization process ignores them and returns an empty value for these properties after deserialization is complete. The fix should not affect any REST or OData services as these service types never supported Interfaces, Abstract Classes, or System.Object properties due to how they operate.
To determine if the fix affected any of your solutions, go through all SmartObjects based on these service types and determine if any SmartObject has a property that shows the type as "(Object)" (this is dependent on the Service Instance to have the "Names: Add property types" set to true).
Below is an example of a custom WCF service that exposes an Interface property called "RobotInUse"
Addressing post-mitigation issues
If you run into an issue after applying the fix specifically related to not supporting Interface, Abstract Class, or System.Object properties, you can work around the problem if the backend service is in your control and you are able to change the structure of the executed methods. Instead of requiring a loosely-typed object, change the methods or objects to take in simple-typed values which the service, instead of K2, then converts to the required object. See the example below.
Example:
In the following example the assembly's code for an Endpoint Assembly service instance changes to take in a string instead of a System.Object, and then the value deserialzes inside the method.
Code before:
{
if (value != null)
{
value.Start();
return "success";
}
return "failure";
}
Code After:
{
var robot = Deserialize(value, typeof(CleaningRobot));
if (robot != null)
{
robot.Start();
return "success";
}
return "failure";
}