concept read - once object in category security

appears as: read-once objects, A read-once object, read-once object
Secure by Design

This is an excerpt from Manning's book Secure by Design.

Both credit card numbers and SSNs have strong restrictions on how they can be revealed, put into logs, and so on. If they are represented as strings, there’s a risk that they’ll be accidentally put into logs or shown. Later, we’ll see how representing these things as domain classes can avoid such mistakes; for example, by using read-once objects (we cover this in chapter 5).

A read-once object is, as the name implies, an object designed to be read once. This object usually represents a value or concept in your domain that’s considered to be sensitive (for example, passport numbers, credit card numbers, or passwords). The main purpose of the read-once object is to facilitate detection of unintentional use of the data it encapsulates. Often this object is a domain primitive, but you can apply this pattern to both entities and aggregates as well. The basic idea is that once the object has been created, it’s only possible to retrieve the data it encapsulates once. Trying to retrieve it more than once results in an error. The object also makes a reasonable effort to prevent the sensitive data from being extracted through serialization.

An example of a read-once object is shown in listing 5.3. As you can see, the SensitiveValue object has been modeled as a domain primitive with all its invariants enforced at creation. The class is declared as final to prevent subclassing, and the value is wrapped in an AtomicReference.6  When the accessor method value is called, it sets the sensitive value to null and then returns the previous value. If value has already been called, then the previous value will be null and an exception is thrown.

Figure 5.4 The life cycle of a read-once object

figure05-04.eps

Passwords are a typical example of sensitive data. The last thing you want is the user’s password to end up as plain text in some log file on disk where anyone can read it, or written out in an error message in the user’s browser or in a monitoring dashboard for your operations team to see. If you model your password as a domain primitive and implement it as a read-once object, as shown in the following listing, you’re creating a safety net that helps you easily detect if the password starts to leak somehow.