Software Security Institute
Software Security Institute

Home > courses

Register For
Upcoming Events

No Events Scheduled

Developer 548 ::

Secure Coding in C: Developing Defensible Applications

Overview

Producing secure programs requires secure designs. However, even the best designs can lead to insecure programs if developers are unaware of the many security pitfalls inherent in C and C++ programming.

This course provides a detailed explanation of common programming errors in C and C++ and describes how these errors can lead to code that is vulnerable to exploitation. The tutorial concentrates on security issues intrinsic to the C and C++ programming languages and associated libraries. The intent is for this tutorial to be useful to anyone involved in developing secure C and C++ programs, regardless of the specific application.

The tutorial assumes basic C and C++ programming skills but does not assume an in-depth knowledge of software security. The ideas presented apply to various development environments, but the examples are specific to Microsoft Visual Studio and Linux/GCC and the 32-bit Intel Architecture (IA-32). Material in this presentation was derived from the Addison-Wesley book Secure Coding in C and C++.

Subjects covered in the first two days are general, but examples are taken from both the Microsoft Visual Studio and GCC compilers on Windows and Linux platforms. Course material on integers uses examples from the IA-32 architecture.

The third and fourth days of the course focus on POSIX platforms. Doug Lea's malloc (dlmalloc) is used to demonstrate exploits in the Linux environment, while the file I/O sections focus on Unix and the Unix file system (UFS).

TOPICS
  • String Management
  • Dynamic Memory Management
  • Integral Security
  • Formatted Output
  • File I/O
OBJECTIVES

Participants should come away from this course with a working knowledge of common programming errors that lead to software vulnerabilities, how these errors can be exploited, and effective mitigation strategies for preventing the introduction of these errors. In particular, participants will learn how to accomplish the following:

  • Improve the overall security of any C or C++ application
  • Thwart buffer overflows and stack-smashing attacks that exploit insecure string manipulation logic
  • Avoid vulnerabilities and security flaws resulting from the incorrect use of dynamic memory management functions
  • Eliminate integer-related problems: integer overflows, sign errors, and truncation errors
  • Correctly use formatted output functions without introducing format-string vulnerabilities
  • Avoid I/O vulnerabilities, including race conditions

Moreover, this course encourages programmers to adopt security best practices and develop a security mindset that can help protect software from tomorrow's attacks, not just today's.

Pre-requisites:

It is recommended that participants have a basic to intermediate understanding of the C and C++ program

Extra Items Needed:

The Secure Coding in C and C++ book authored by Robert C. Seacord and published by Addison-Wesley will be provided.

Laptop

Students must bring a personal computer equipped with:

Day Information

Day 1
Day 1

The incorrect use of null-terminated byte strings is the most common source of vulnerabilities, particularly buffer overflows, in the C and C++ languages.

This first day of the course introduces the null-terminated byte string data type and describes common errors manipulating this data type. We then illustrate how these errors can lead to buffer overflows, stack smashing, and arc injection attacks. The first exercise requires students to identify common string errors in existing source code.

Code inspections (also referred to as security audits) are an established mechanism for eliminating software vulnerabilities, but are typically unstructured and rely on the knowledge and the tenacity of the reviewers. The afternoon of the first day we describe a method for performing structured code reviews with the intent of eliminating buffer overflows from source code. There is also an exercise to allow students to become familiar with applying this method.

Day 2
Day 2

Integers represent a growing and underestimated source of vulnerabilities in C and C++ programs. Integer range checking has not been systematically applied in the development of most C and C++ software. Consequently, security flaws involving integers exist and a portion of these are likely to be vulnerabilities. The second day of the course focuses on integers in C and C++, including integer representation, types, conversions, error conditions, and operations.

Vulnerabilities resulting from integer errors are examined, as well as appropriate mitigation strategies. These exercises build from exercise one on the first day. In exercise three you reexamine the code from exercise one to identify integer problems. In exercise four, you repair both the string and integer problems discovered in the earlier exercises.

Day 3
Day 3

Day three focuses on dynamic memory management and formatted output. Dynamic memory management is a well-known source of errors in C and C++ programming, but it is not as well known that that these errors can frequently be exploited to execute arbitrary code. We'll examine common memory management errors and examine how these errors may be exploited, using Doug Lea's malloc (dlmalloc) and Linux as an example. In the fifth exercise you will use valigrind to identify memory errors in some sample code. A Linux virtual machine image is provided, or you can use your own installation. Formatted output is also examined on the third day, including how buffer overflows and format string vulnerabilities may be exploited by attackers and how to defend against such attacks.

Day 4
Day 4

File I/O is covered on the fourth and final day. Software vulnerabilities resulting from incorrect interactions with the file system, privilege mismanagement, and race conditions are all examined in the context of POSIX and Unix file systems. Because secure file I/O operations require the use of platform specific interfaces, we'll focus on issues and mitigation strategies specific to POSIX systems. Many of the issues involving file I/O are common to other platforms, however. In the sixth and final exercise, you will find and eliminate file I/O vulnerabilities from the sample program used in exercise five.