Poor software design and engineering are the root causes of most security vulnerabilities in deployed systems today. This course will examine approaches, mechanisms, and tools used to make software systems more secure. We will motivate the study by discussing common software security threats (e.g., buffer overflow attacks and cross-site scripting). The majority of the course will be divided into four main modules: run-time enforcement of security policies (e.g., dynamic taint analysis); architectural approaches to building secure software (e.g., confinement, virtual machines, trusted computing); software analysis (e.g., static analysis and testing, model checking); and language-based approaches to building secure software (e.g., type systems, proof-carrying code). Time permitting, the course also covers topics such as the importance of usability to building secure software systems.