Introduction to security design



Winter 2 batch


What we're covering

tl;dr: system-level stuff

What we're not covering

Secure programming

Secure programs are subsets of correct programs

No program is 100% correct

Hence: security bugs

Memory safety bugs


Dangling pointers

Buffer overflows

Moar bugs!

Race conditions

Resource leaks

Example: buffer overflows

When a program writes past the end of a buffer

The write overflows out of the allocated memory region

Stack-based exploitation (aka stack smashing)

Based on overwriting something

Security-critical information: e.g. a variable in a stack frame

Execution-related pointers: e.g. function pointers, stack frame return addresses, exception handlers

Easiest solution: memory-safe languages

Python, Ruby, JavaScript, etc. - already memory-safe

C and C++ -> Rust

Otherwise: tools


Your compiler (-fstack-protector[-all])

OS tools (e.g. memory junking, ASLR)

Don't make your tools useless (Heartbleed)

Also helpful: reducing attack surface

Attack surface = how much of your program is exposed to attack

If your program doesn't ever encounter an attacker, that's zero attack surface

Example: Tor Browser's security slider

Other bugs besides memory safety

Assume your program will be compromised

Preventative measures

Principle of least privilege

Makes sense if you assume security bugs

Obvious example: don't run things as root

Dropping privileges

Start as root

Do some stuff (e.g. bind to a restricted port)

Set the user the program's running under to an unprivileged user


Dividing your program up

Multiple processes

Multiple security domains

Each restricted as much as possible

Example: ntpd

Sets the time of day (requires root)

Speaks UDP to time servers

Queries the DNS

OpenBSD ntpd

Good example: Chrome


Make sure requests make sense

Confused deputy attack

chroot jails

Chroot() causes dirname to become the root directory, that is, the starting point for path searches of pathnames beginning with `/'. - chroot(2)

Restrict which parts of the filesystem can be used

chroot example - setup

$ pwd

$ ls /home

$ mkdir chroot-jail/{,bin,lib,lib64}

$ for i in bin lib lib64; do
>   sudo mount --bind /$i chroot-jail/$i
> done
[sudo] password for alex:

chroot example - setup

$ tree chroot-jail
├── bin
│   ├── bash
│   └── zsh5
└── lib
    ├── cpp -> /etc/alternatives/cpp
│   └──
└── lib64
    └── -> /lib/[...]

2311 directories, 10645 files

chroot example - jailing

$ sudo chroot chroot-jail

# pwd

# ls /home
ls: cannot access /home: No such file or directory

# ls /
bin  lib  lib64

# exit

$ pwd

We prevented ourselves from accessing /home


Normally programs don't need this setup

Secure coding: have your program put itself in a jail

Note: root can break out of chroot jails

There are more tools, but they're not portable

Almost fin

In general, just remember: your program will get pwnd

(But still try to mitigate exploits and reduce attack surface)


Final notes: anything the OpenBSD guys do is excellent

Six dumbest ideas in computer security


Access this presentation again

Or get the source code