What syntax would I use to get the number of bytes representing a string and compare them to the number of bytes representing an ArrayList
holding that string, for example?
The Java deserialization vulnerability (CVE 2015-7501 and CWE-502, disclosed in January 2015) affects specific classes within the Apache Commons-Collections library prior to versions 3.2.2 and 4.1; this vulnerability allows remote code execution by an unauthenticated attacker. Java Deserialization Security FAQ. This FAQ (in the form of a living document, being updated once in a while) covers some questions I've been asked after talking about Java deserialization vulnerabilities at conferences during the last months. Are other formats than Java serialization affected?
I am using a multi-agent agent system to send objects via messages and I want to keep track of how much space each message takes up. The method doesn't have to be dead-on accurate, as long as it scales proportionally to the actual size of the object. E.g. a Vector of strings of length 4 will report as smaller than a Vector of strings of length 5.
5 Answers
You can convert your object into a byte array using ObjectOutputStream
and ByteArrayOutputStream
:
I just tested this out. The object who's size you're trying to calculate, needs to implement Serializable
(which means you may have to mark every object as such simply to get its size. Might not be desirable). I wrote a quick and dirty program to test this out:
Which gave me:
EDIT
![Java Vulnerability Bug Serializable Java Vulnerability Bug Serializable](https://diablohorn.files.wordpress.com/2017/09/normaldeser.png)
Stephen C's answer highlights some caveats with this method.
I needed to check this accurately per-memcache write while investigating a server bug where memcache sizes were exceeded. To avoid the overhead of a big byte array for large objects I extended OutputStream as a counter:
You can serialise each object into arrays and compare the length of each array. This is not very accurate, in the general case, but often gives a good approximation.
Have a look at ObjectOutputStream (which can be used to serialise an object and turn it into Bytes) and ByteArrayOutputStream (which can be used to hold the serialised bytes).
I don't think you've got much choice but to modify your code so that it measures the message sizes at runtime.
You could just serialize example objects and capture and measure the serialized size. This has the following problems:
- You can never be sure that the objects are typical.
- Various aggregation effects mean that it is hard to deduce the size of a message from the serialized size of its component objects. (For instance, class signatures are only encoded once per serialization.)
- This approach tells you nothing about the relative frequency of different message types.
If you can manage this, you will get more accurate results if you can measure the actual messages. This would most likely entail modifying the agent framework to count, measure and (ideally) classify messages into different kinds. The framework might already have hooks for doing this.
The method doesn't have to be dead-on accurate, as long as it scales proportionally to the actual size of the object. E.g. a Vector of strings of length 4 will report as larger than a Vector of strings of length 5.
(I assume that you meant smaller than ...)
Your example illustrates one of the problems of trying to estimate serialized object sizes. A serialization of a Vector<String>
of size 4 could be smaller ... or larger ... that a Vector<String>
of size 5. It depends on what the String values are. Additionally, if a message contains two Vector<String>
objects, the serialized size occupied by the vectors will be less that sum of the sizes of the two vectors when they are serialized separately.
have a look at: http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html
closest thing that comes to mind would be serializing it and reading the num of bytes