Procuret Blog

Data Security

Hugh Jeremy

07 September 2021

Data are the most valuable resource on Earth. No matter your product, your company collects, stores, transforms, and retrieves data.

Those data describe your company. They describe your customers. They describe you. In malicious hands they enable theft, fraud, blackmail, and reputational destruction against your company, your customers, and yourself.

You have an obligation to defend data. This article will present five principles that you can use to defend your data along with practical examples:

  1. Arm your data to defend themselves
  2. Defend in depth
  3. Present a small target
  4. Scan the horizon
  5. Watch the walls

Principle 1: Arm your data to defend themselves

Much discourse around cybersecurity focuses on defending systems. For example: network firewalls, malware detection ("Anti Virus"), and behavioural heuristics. This is well and good. However, the system only exists to store, transform, and retrieve data. When considering how to defend data, we should not start at the systems level. We should start at the level of the data themselves.

Consider a model of the flow of data from your datastore during a request:

At step two you are in a position to defend the data. Your existing authentication & authorisation ("Auth") subsystem will have yielded an authenticated agent. You can now give the data themselves the final say over whether that agent gets to read them. In code, you might implement this as "protocol", or "interface", wherein you guarantee the availability of a method that, when called, tells the caller whether read should be granted to the requesting agent.

For example, in Python:

class ReadProtected:
    def grants_read_to(self, agent: Agent) -> bool:
        raise NotImplemented

Or in Swift:

protocol ReadProtected {
    func grantsReadTo(agent: Agent) -> Bool
}

Such a protocol may then be incorporated into your serialisation subsystem. Suppose data to be serialised must themselves conform to a Serialisable protocol. At the point where data are about to leave your network, you can combine the two protocols.

For example, in Python:

class Serialisable(ReadProtected):
    def serialise_for(self, agent: Agent) -> str:
        if not self.grants_read_to(agent=agent):
            raise NotAuthorised
        # Proceed to serialise...

Or in Swift:

protocol Serialisable: ReadProtected {
    func serialiseFor(agent: Agent) throws -> String
}
extension Serialisable {
    func serialiseFor(agent: Agent) throws -> String {
        if !self.grantsReadTo(agent: agent) {
            throw NotAuthorised
        }
        // Proceed to serialise...
    }
}

While these examples are dramatically simplified, they do represent how Procuret API functions in the real world. Data are given the final say over whom they are transmitted to. In this way, entire classes of authorisation bugs are eliminated. It becomes much, much harder to accidentally transmit data to an unauthorised agent.

Principle 2: Defend in depth

In 1939, France felt impregnable. An immense line of fortifications ran along the border with Germany, stopping at the Adrennes forest. These fortifications were so impossibly strong that secondary defenses were barely considered. That year, Germany drove around the northen end of the Maginot line, through the undefended Ardennes forest. You know how it goes from there.

In 2020, the United States government and countless private firms began a collective uncontrolled venting of private, sensitive data into the waiting arms of Russia. They had depended on a security outsourcing company called SolarWinds to protect their data.

Russia infiltrated the systems used to build SolarWinds software products via weaknesses in Microsoft's Office 365 email product. Russia rewrote SolarWinds software to do their bidding. SolarWinds products, designed to defend against attack, literally became the weapon.

SolarWinds was the U.S. government's Maginot Line. Office 365 was the Ardennes forest. Behind SolarWinds, no mechanisms were in place to prevent Russia manouvering through Departments of Defense, Treasury, and Homeland Security and other sensitive systems.

To defend your data, you must defend "in depth". This means that you assume your first line of defense will fail, and the second, and the third, and so on. At each failure, present defenses to mitigate damage.

In practice, your defense in depth will depend on the precise characteristics of your software, hardware, and operations. You can plan for your circumstances by theorising scenarios.

For example, what happens to your data if...

  1. A salespersons's email account is compromised
  2. Web server software has an unpatched remote-code-execution flaw
  3. Your third-party security company "pulls a SolarWinds"

These are uncomfortable questions. You had best get comfortable answering them because they are historically highly likely to happen.

Principle 3: Present a small target to the enemy

The internet is a terrifying place. As soon as you connect a system to the internet, it can be attacked. Before evaluating how to defend a system, consider whether you can move it out of the line of fire.

In cybersecurity jargon, this is called reducing the "attack surface" available to the adversary.

One of the easiest things you can do to reduce your attack surface is get as many of your machines off the internet as possible. Machines that are not addressable on the internet are not invulnerable, an attacker can still traverse your network to reach them. But risk is dramatically reduced.

In practice this means only giving machines local network addresses, either on your own physical network or on a virtualised network (such as inside Amazon Web Services or Microsoft Azure). Parties that must be able to access machines, such as system administrators, must do so only via a Virtual Private Network whose entry point is itself one of your machines. WireGuard and OpenVPN are easy ways to achieve this.

At Procuret, the only machines addressable by the internet are those terminating HTTP requests at procuret.com.

Principle 4: Scan the horizon

I don't know about you, but I would rather see the punch coming. It is not sufficient to defend against known threats. We must keep an eye on emerging threats.

Fortunately, there are lots of clever, noble people out sharing their knowledge. By listening to the right conversations, you have a chance to see attacks in progress before they hit your systems.

Twitter is an absolute gold mine of this kind of knowledge. Here are a few accounts to get you started:

Principle 5: Watch the walls

Your company has been attacked. Either you know this to be true, or you must assume it to be true. If you don't think you have been attacked, you are either ignorant, arrogant, or your company does not have a website.

Here's an example of data collected during an attempt to probe Procuret for SQL injection vulnerabilities:

And here is an example of an attempt to exploit a Microsoft Exchange vulnerability at Procuret a just a week ago:

(Excuse my use of our out-dated Twitter handle... It's now @ProcuretPay)

Do you have records of attacks? If you don't, it is very likely you are not seeing aggressors probing your system. A simple way to get started is to log HTTP data associated with any unexpected exceptions emitted by your software. You can then look for for telltale signatures (such as the /owa/auth/x.js path in the above screenshot), and assess whether you are safe against whatever attack vector malicious party is probing.

The end

That's all for now, folks. If you would like to chat about data security, hit me up on Twitter - @hugh_jeremy.

< Blog home