Dissecting the 'Obfuscated Transfer Object'

      2 Comments on Dissecting the 'Obfuscated Transfer Object'

One thing I noticed lately…is lot of interest about understanding the usage of ‘Obfuscated Transfer Object (OTO) ‘ from Core Security Patterns.  I got multiple emails about its code and implementation .. understandably there is a growing security concern about using Transfer Object (aka Value Object) that passes security-sensitive data elements between Java EE tiers (especially between Presentation/Business/Persistence), when the application components does’nt run in a co-existing environment and risks associated with getting captured in console messages, log files and by rogue administrators. Think about “User Profile” or “Credit Card” or any other sensitive data in transit, it becomes quite critical to ensure privy of the data with appropriate data protection in place.  When we wrote Core Security Patterns, Chris and I discussed more  about this pattern and its implementation than anything else….agreed, this has its own implementation complexities . The worst you could see is, if you screw up the implementation it masks all the Java EE components from consuming the data elements of the passed OTO…. from a security perspective, it is a good thing as it fails safely.

Let’s dig into the finer details of why and how you would choose to implement an Obfuscated Transfer Object:

Why OTO ?

  • To protect sensitive data passed in Transfer Objects from being captured in console messages (JMX, Adminstration), log files and audit logs.
  • To ensure Transfer object be responsible for protecting the data and prevent target application components from inadverently exposing sensitive data.
  • To protect select data elements and not all data elements should be protected or exposed.

How it works ?

In simpler terms, Obfuscated Transfer Object allows  to define data elements within it that are to be protected using mechanisms to prevent purposeful or inadvertent unauthorized access to its data. The means of protection can vary between applications or implementations depending on your target business requirements. The OTO provides the producers and consumers of the data can agree upon the sensitive data
elements that need to be protected and on their means of access. OTO will then take the responsibility of protecting that data from any intervening components that it is passed to on its way between producer and consumer. For example, Credit card and other sensitive information can be protected from being accidentally dumped to a log file or audit trail, or worse, such as being captured and stored for malicious purposes.

How to Implement OTO ?

Although there are several ways to implement OTO, the two easier ways we found to implement OTO are  Masked List Strategy and Sealed Object/Encryption Strategy.

Masked List Strategy

In this strategy, the client sets data as name-value (NV) pairs in the Obfuscated Transfer Object. Internally, the Obfuscated Transfer Object maintains two maps, one for holding NV pairs that should be obfuscated and another for NV pairs that do not require obfuscation. In addition to the two maps, the Obfuscated Transfer Object contains a list of NV pair names that should be protected. Data passed in with names corresponding to names in the masked list, are placed in the map for the obfuscated data. This map is then protected. In the sequence above, when the Component logs the ObfuscatedTransferObject, the data in the obfuscated map is not logged, and thus it is protected.

Sealed Object/Encryption Strategy

With encryption Strategy for Obfuscated Transfer Object provides the highest level of protection for the data elements protected within. The data elements are stored in a Data Map, and then the Data Map as a whole is encrypted using a symmetric key. To retrieve the Data Map and the elements within it, the consumer must supply a symmetric key identical to the one used by the producer to seal the Data Map.

private SealedObject sealedMap;
// Seal object
HashMap map = sealedMap.getObject(cipher);
// Unseal object
sealedMap = new SealedObject(map, cipher);

As shown above, we can implement this using Java Sealed Object class that allows to easily encrypt objects by passing in a serialized object and a Cipher object in the constructor. The serialized object can then be retrieved by either passing in an identical Cipher or a Key object that can be used to recreate the Cipher. This encapsulates all of the underlying work associated with encrypting and decrypting objects. The only issue remaining is the management of symmetric keys within the application. This poses a significant challenge because it requires the producers and consumers to share symmetric keys without providing any intermediary components with access to those keys. This may be simple or overwhelmingly complex depending on the architecture of the application and the structure of the component trust model. Use this strategy with caution, because the key-management issues may be harder to overcome than architecting the application again to eliminate the need for the Sealed Object :-).

Hope this helped my two EU friends…who keep pestering me last two days via email. Due to my contractual obligations with Prentice Hall, I cannot dump the contents and source code in my blog…so I leave the rest to your way and you know where to look for :-). Also don’t ask how it is being implemented in Microsoft .NET – that’s not my forte.

2 thoughts on “Dissecting the 'Obfuscated Transfer Object'

Leave a Reply

Your email address will not be published. Required fields are marked *