...
By providing overridden implementations, an attacker can use untrusted code to glean sensitive information, run arbitrary code, or launch a denial of service attack.
See MET52-JG 10. Do not use the clone() method to copy untrusted method parameters for more specific details regarding overriding the Object.clone()
method.
...
Code Block |
---|
public class CraftedLicenseType extends LicenseType { private static int guessedHashCode = 0; @Override public int hashCode() { // Returns a new hashCode to test every time get() is called guessedHashCode++; return guessedHashCode; } @Override public boolean equals(Object arg) { // Always returns true return true; } } |
Following The following is the malicious client program:
...
The client program runs through the sequence of all possible hash codes using CraftedLicenseType
until it successfully matches the hash code of the demo license key object stored in the LicenseManager
class. Consequently, the attacker can discover the sensitive data present within the licenseMap
in only a few minutes. The attack operates by discovering at least one hash collision with respect to the key of the map.
Compliant Solution (IdentityHashMap
)
This compliant solution uses an IdentityHashMap
rather than a HashMap
to store the license information:
...
Code Block |
---|
public class DemoClient { public static void main(String[] args) { LicenseManager licenseManager = new LicenseManager(); LicenseType type = new LicenseType(); type.setType("custom-license-key"); licenseManager.setLicenseKey(type, "CUS-TOM-LIC-KEY"); Object licenseKeyValue = licenseManager.getLicenseKey(type); // Prints CUS-TOM-LIC-KEY System.out.println(licenseKeyValue); } } |
Compliant Solution (final
...
Class)
This compliant solution declares the LicenseType
class final so that its methods cannot be overridden:
...
Code Block |
---|
public class Navigator extends Widget { public Navigator(int noOfComponents) { super(noOfComponents); } @Override public int hashCode() { int res = 31; res = res * 17; return res; } } |
Client The client code follows:
Code Block |
---|
Widget nav = new Navigator(1); Widget widget = new Widget(1); LayoutManager manager = new LayoutManager(); manager.addWidget(nav); manager.addWidget(widget); System.out.println(manager.getLayoutSize()); // Prints 2 |
...
The reason for this discrepancy is that the hashCode()
method of Widget
is used only once when the widget is added to the set. When the navigator is added, the hashCode()
method provided by the Navigator
class is used. Consequently, the set contains two different object instances.
Compliant Solution (final
...
Class)
This compliant solution declares the Widget
class final so that its methods cannot be overridden:
...
Code Block |
---|
Worker w1 = new Worker(); w1.startThread("parent-thread"); Worker w2 = new SubWorker(); w2.startThread("child-thread"); |
Bibliography
[API 20112013] | Class IdentityHashMap |
[Hawtin 062006] | [drlvm][kernel_classes] ThreadLocal vulnerability |
...