Announcement
Project 2 Due
Project 3 will be out this weekend
Designing and Writing Secure Code
Outline
General principles
Least privilege, defense in depth,
Buffer Overflow Example
Sendmail vs qmail
Tools for secure coding
Type-safe programming languages
Code analysis algorithms
Run-time monitoring
General Principles
Compartmentalization
Principle of least privilege
Minimize trust relationships
Defense in depth
Use more than one security mechanism Secure the weakest link Fail securely
Keep it simple Consult experts
Dont build what you can easily borrow/steal
Open review is effective and informative
Compartmentalization
Divide system into modules
Each module serves a specific purpose
Assign different access rights to different modules
Read/write access to files Read user or network input Execute privileged instructions (e.g., Unix root)
Principle of least privilege
Give each module only the rights it needs
Example
Compartmentalization (II)
Sendmail runs as root
Root privilege needed to bind port 25
No longer needed after port bind established
But most systems keep running as root
Root privileges needed later to write to user mailboxes
Will look at qmail for better security design
Minimize trust relationships
Clients, servers should not trust each other
Both can get hacked
Trusted code should not call untrusted code
Defense in Depth
Failure is unavoidable plan for it Have a series of defenses
If an error or attack is not caught by one mechanism, it should be caught by another
Examples
Firewall + network intrusion detection
Fail securely
Many, many vulnerabilities are related to error handling, debugging or testing features, error messages
Secure the weakest link
Think about possible attacks
How would someone try to attack this? What would they want to accomplish?
Find weakest link(s)
Crypto library is probably pretty good
Is there a way to work around crypto?
Data stored in encrypted form; where is key stored?
Main point
Do security analysis of the whole system Spend your time where it matters
Keep It Simple
Use standard, tested components
Dont implement your own cryptography
Dont add unnecessary features
Extra functionality more ways to attack
Use simple algorithms that are easy to verify
A trick that may save a few instructions may
Make it harder to get the code right
Make it harder to modify and maintain code
Security by Obscurity Is NOT Secure !!!
Hiding sensitive information is hard Information in compiled binaries can be found
Reverse engineering
Disassembler: machine code to assembly Discomplier: machine code to high-level language
Insider attacks are common
Firewalls do not protect against inside attacks
Dont reinvent the wheel
Consult experts
Allow public review
Use software, designs that other have used Examples
Bad use of crypto: 802.11b
Protocols without expert review: 802.11i
Use standard url parser, crypto library, good random number generater,
Example: Mail Transport Agents
Sendmail
Complicated system
Source of many vulnerabilities
Qmail
Simpler system designed with security in mind Gaining popularity Qmail was written by Dan Bernstein, starting 1995 $500 reward for successful attack; no one has collected
Simplified Mail Transactions
Mail User Agent Mail Transport Agent Mail Transport Agent Mail User Agent
mbox
Mail Delivery Agent
Mail Delivery Agent
mbox
Message composed using an MUA MUA gives message to MTA for delivery
If local, the MTA gives it to the local MDA If remote, transfer to another MTA
Example: Qmail
Compartmentalize
Nine separate modules If one module compromised, others not
Move separate functions into mutually untrusting programs
Always validate input from other modules
THE BIG Qmail PICTURE
SMTP from network remote mailserver tcpserver / tcp-env / inetd from local
MUA
qmail-smtpd
qmail-inject
forwarded message qmail-queue qmail-system qmail-send
qmail-rspawn
qmail-lspawn
qmail-remote
qmail-local mbox / maildir / program delivery
remote mailserver
to local
Structure of qmail
qmail-smtpd qmail-queue Incoming SMTP mail qmail-send qmail-rspawn qmail-lspawn Other incoming mail qmail-inject
qmail-remote
qmail-local
Structure of qmail
qmail-smtpd Splits mail msg into 3 files
Message contents 2 copies of header, etc.
qmail-inject qmail-queue
qmail-send qmail-lspawn
Signals qmail-send qmail-rspawn
qmail-remote
qmail-local
Structure of qmail
qmail-smtpd qmail-send signals
qmail-lspawn if local qmail-remote if remote
qmail-inject qmail-queue
qmail-send qmail-lspawn
qmail-rspawn
qmail-remote
qmail-local
Structure of qmail
qmail-smtpd qmail-queue qmail-inject
qmail-send qmail-lspawn
qmail-lspawn
Spawns qmail-local qmail-local runs with ID of user receiving local mail
qmail-local
Structure of qmail
qmail-smtpd qmail-queue qmail-inject
qmail-send qmail-lspawn
qmail-local
Handles alias expansion Delivers local mail Calls qmail-queue if needed
qmail-local
Structure of qmail
qmail-smtpd qmail-queue qmail-inject
qmail-send qmail-rspawn qmail-remote qmail-remote
Delivers message to remote MTA
Least Privilege in Qmail
Each module uses least privileges necessary Each runs under different non-privileged UID in three groups: qmaild, qmailr, qmails
Except one as root
Only one run as root (except qmail-start)
Spawns the local delivery program under the UID and GID of the user being delivered to Always changes effective uid to recipient before running user-specified program
Least privilege
qmail-smtpd qmail-inject qmail-queue
setuid
qmail-send qmail-rspawn qmail-lspawn
root
qmail-remote
qmail-local
Principles, sendmail vs qmail
Do as little as possible in setuid programs
Of 20 recent sendmail security holes, 11 worked only because the entire sendmail system is setuid Only qmail-queue is setuid
Its only function is add a new message to the queue Setuid to the user ID of the qmail queue owner, not root No setuid root binaries
Do as little as possible as root
The entire sendmail system runs as root
Operating system protection has no effect
Only qmail-start and qmail-lspawn run as root.
root
root
inetd qmaild
qmail-start
Start qmailsend & queue management
UIDs
user
qmail-smtpd
qmail-inject
qmail-queue
setuid
qmail-send
qmailr qmails
qmails
qmail-rspawn
qmail-lspawn
setuid user
root
root
user
qmailr
qmail-remote
qmail-local
Parsing
Keep it simple
Limited parsing of strings
Minimizes risk of security holes from configuration errors
Modules do parsing are isolated and run with user privilege
Libraries
Avoid standard C library, stdio
Write bug-free code (DJB)
Small code is more secure
Plug in interposing modules rather than complicating the core code
Comparison
Lines qmail-1.01 sendmail-8.8.8 zmailer-2.2e10 smail-3.2 exim-1.90 16028 52830 57595 62331 67778 Words 44331 179608 Chars 370123 1218116 Files 288 53 227 151 127
205524 1423624 246140 1701112
272084 2092351
Comparison with other MTAs
MTA Qmail Maturity Security Features Perform ance Medium High High High Low High High Medium Low High Modular Yes No Yes
Sendmail High Postfix Medium
Secure Programming Techniques: An Abstract View of Program
Program Component Avoid buffer overflow Secure software design Language-specific problems Application-specific issues Call other code carefully
Validate input
Respond judiciously
Secure Programming
Validate all your inputs
Command line inputs, environment variables, CGI inputs,
Don't just reject bad input, define good and reject all else
Avoid buffer overflow Carefully call out to other resources
Check all system calls and return values
Backup Slides