Skip to content

1. Security Principles

This note describes the basic security principles one should consider when implementing anything computer security related.

Know Your Threat Model

Threat mode: model of who your attacker is and what resources they have.

Here are some commone assumptions we take into account for attackers:

  1. Attacker can interact with your systems without anyone noticine, meaning you might not always be able to detect the attacker tampering with your system before they attack
  2. Attacker has general information about your system, such as the OS, any potential software vulnerabilities, etc.
  3. Attacker is persistent and lucky; for example any vulnerability left to chance should be assumed to work for the attacker
  4. Attacker has resources required to undertake the attack (such as computation power, money, etc.)
  5. Attacker can coordinate several complex attacks across various systems, so they can attack your entire network at the same time
  6. Every system is a potential target. For example, a casino was once hacked because a fish-tank thermometer was hacked within the network.

Also consider old code where the threat model might have changed. The Internet was mostly populated by academics who trusted one another. Now there are billions of devices, some of them are malicious.

Consider Human Factors

There are also other non-coding related factors to consider

  1. Programmers themselves mighjt make mistakes and use tools that allow them to make mistakes
  2. Users like convenience, so if a security system is unusable and not user-friendly, no matter how secure it is, it will go unused
  3. Social engineering attacks are when one exploits other's trust and access for personal gain

Security is Economics

Sometimes more security means more costs, more money. But also sometimes one needs to consider the relation between the expected benefit of defense and the expected cost of the attack (such as putting a $100 lock on a $1 item).

A corollary of this principle is that you should focus your energy on securing the weakest links. A system is only as secure as the weakest link. Attackers follow the path of least resistance, and they will attack the system at its weakest point.

A related principle is conservative design, which states that systems should be evaluated according to the worst security failure that is at all plausible, under assumptions favorable to the attacker.

Detect If You Can't Prevent

Detection is simply learning tha the attack has taken place, and response would be doing something about the attack. When dealing with a response, you should always assume bad things will happen, and therefore prepare your systems for the worst case outcome. You should plan security in a way that lets you get back to some form of a working state a (like keeping offsite backups of computer systems).

Defense In Depth

Defense in depth is the idea that multiple types of defenses should be layered together so an attacker would have to breach all the defenses to successfully attack a system.

Least Privilege

This is the idea that one should give a program a set of access privileges that it legitmately needs to do its job but nothing more. This is a powerful approach -- although it doesn't reduce the probably of failure, it can reduce the expected cost of failures, such as in the case of buffer overflows.

Separation of Responsibility

Split up privilege, so that no one person has complete power. Require more than one party to approve before access is granted.

Ensure Complete Mediation

Make sure that you check every access to every object. On eway to accomplish this is through a reference monitor, which is a single point through which all access must occur.

Shannon's Maxim

States that the attacker knows the system that they are attacking.

Security through obscurity: refers to systems that rely on the secrecy of their design, algorithms, or source code to be secure. However, it is extremely brittle and is ofted difficult to keep the design of a system secret from a sufficiently motivated attacker.

This doesn't mean that open-source applications are necessarily more secure than closed-source applications. Never rely on obscurity as part of your security. Always assume that the attacker knows every detail about the system that you are working with.

Kerckhoff's Principle: cryptographic systems should remain secure even when the attacker knows all internal details of the systems. The secret key should be the only thing that must be kept secret, and the system should be designed to make it easy to change keys that are leaked (or suspected to be leaked).

Use Fail-Safe Defaults

Choose default setting that "fail safe", balancing security with usability when a system goes down. Ensure that if the security mechanisms fail or crash, they will default to secure behavior, not insecure behavior.

For example, firewalls explicitly decide to foward a given packet or else the packet is lost. If a firewall suffers a failure, no packets will be forwarded.

Design Security in From the Start

Retrofitting security to an existing application after it has already been spec'ed, designed, and implemented is usually very difficult. Look to the Internet as a whole as an example.

The Trusted Computing Base (TCB)

TCB is that portion of the system that must oerate correctly in order for the security goals of the system to be assured. We have to rely on every component in the TCB to work correctly. HOwever, anything that is outside the TCB isn't relied upon in any way; even if it misbehaves or operates maliciously, it cannot defeat the system's security goals.

TCB is made to be small as possible since a smaller, simpler TCB is easier to write and audit.

TCB Design Principles: 1. Unbypassable (or completeness): There must be no way to breach system securit by bypassing the TCB 2. Tamper-resistat (or security): The TCB should be protected from tampering by anyone else. 3. Verifiable (or correctness): It should be possible to verify the correctness of the TCB. This usually means the TCB should be as simple as possible.

TCB simple and small: less code you have to write, the fewer changes you have to make a mistake or introduce some kind of implementation flaw. Industry error rates are 1-5 defects/1000 lines of code.

Benefits of TCB: 1. Allows a primitive yet effective form of modularity 2. Lets us separate the system into two parts (the security-critical (TCB) and everything else

Summary of good principles: 1. Know what is in the TCB. Design your system so that the TCB is clearly identifiable 2. Try to make the TCB unbypassable, tamper-resistant, and verifiable 3. Keep It Simple, Stupid (KISS) 4. Decompose for security. Choose an architecture that makes the TCB as simple and clear as possible

TOCTTOU Vulnerabilities

Common failure of ensuring complete mediation involves race conditions. TOCTTOUS (Time of check to time of use) vulnerability arises when enforcing access control policies such as when using a reference monitor:

procedure withdraw(amount w) {
    // contact central server to get balance
    1. let b := balance
    2. if b < w, abort

    // contact central server to set the balance
    3. set balance := b - w
    4. give w dollars to the user
}

With this code, we see that multiple calls to withdraw concurrently can break it. It the attacker knew the execution procedure, they can withdraw infinite amounts of money.

This is TOCTTOU, because between the check and the use of whatever state was checked, the state somehow changed. In the example, between the time that the balance was checked and the time the balance was set, the balance was somehow changed.