icon-carat-right menu search cmu-wordmark

Secure Coding to Prevent Vulnerabilities

Headshot of Robert Seacord
PUBLISHED IN
Secure Development
CITE
SHARE

This post has been shared 1 times.

Software developers produce more than 100 billion lines of code for commercial systems each year. Even with automated testing tools, errors still occur at a rate of one error for every 10,000 lines of code. While many coding standards address code style issues (i.e., style guides), CERT secure coding standards focus on identifying unsafe, unreliable, and insecure coding practices, such as those that resulted in the Heartbleed vulnerability. For more than 10 years, the CERT Secure Coding Initiative at the Carnegie Mellon University Software Engineering Institute has been working to develop guidance--most recently, The CERT C Secure Coding Standard: Second Edition--for developers and programmers through the development of coding standards by security researchers, language experts, and software developers using a wiki-based community process. This blog post explores the importance of a well-documented and enforceable coding standard in helping programmers circumvent pitfalls and avoid vulnerabilities.

Community-Based Development of the CERT C Coding Standard

The idea for the CERT C Coding Standard as a community-based development project arose at the Spring 2006 meeting of the C Standards Committee in Berlin, Germany. Experts from the community, including members of the C Standards Committee, were invited to contribute and were provided with editing privileges on the wiki.

The wiki-based community development process has many advantages; most importantly, this form of collaborative development engages a broad group of experts to form a consensus opinion on the content of the rules. Members of the community can sign up for a free account on the wiki and comment on the coding standards and the individual rules. Reviewers who provide high-quality comments frequently receive extended editing privileges so that they can directly contribute to the development and evolution of the coding standard. Today, the CERT Coding Standards wiki has more than 1,500 registered contributors, and coding standards have been completed for C and Java, with additional coding standards for C++, Perl, and other languages under development. These guidelines and standards, if implemented, could have prevented vulnerabilities, such as Heartbleed.

Heartbleed

Heartbleed emerged as a serious vulnerability in the popular OpenSSL cryptographic software library. This vulnerability allows an attacker to steal information that under normal conditions would be protected by Secure Socket Layer/Transport Layer Security (SSL/TLS) encryption.

Despite the seriousness of the vulnerability, Heartbleed is the result of a common programming error and an apparent lack of awareness of secure coding principles. Following is the vulnerable code:

int dtls1_process_heartbeat(SSL *s) {
unsigned char *p = &s->s3->rrec.data[0], *pl;
unsigned short hbtype;
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */

/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;

/* ... More code ... */

if (hbtype == TLS1_HB_REQUEST) {
unsigned char *buffer, *bp;
int r;

/*
* Allocate memory for the response; size is 1 byte
* message type, plus 2 bytes payload length, plus
* payload, plus padding.
*/
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;

/* Enter response type, length, and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);

/* ... More code ... */
}
/* ... More code ... */
}

This code processes a "heartbeat" packet from a client or server. As specified in the Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension RFC 6520, when the program receives a heartbeat packet, it must echo the packet's data back to the client. In addition to the data, the packet contains a length field that conventionally indicates the number of bytes in the packet data, but there is nothing to prevent a malicious packet from lying about its data length.

The p pointer, along with payload and p1, contain data from a packet. The code allocates a buffer sufficient to contain payload bytes, with some overhead, then copies payload bytes starting at p1 into this buffer and sends it to the client. Notably absent from this code are any checks that the payload integer variable extracted from the heartbeat packet corresponds to the size of the packet data. Because the client can specify an arbitrary value of payload, an attacker can cause the server to read and return the contents of memory beyond the end of the packet data, which violates our recommendation, INT04-C, Enforce limits on integer values originating from tainted sources. The resulting call to memcpy() can then copy the contents of memory past the end of the packet data and the packet itself, potentially exposing sensitive data to the attacker. This call to memcpy() violates the secure coding rule ARR38-C, Guarantee that library functions do not form invalid pointers. A version of ARR38-C also appears in ISO/IEC TS 17961:2013, "Forming invalid pointers by library functions [libptr]." This rule would require a conforming analyzer to diagnose the Heartbleed vulnerability.

The Latest CERT C Coding Standard

Within two years of launching the wiki, the community had developed 89 rules and 132 recommendations for secure coding in C. At that point, a snapshot of the CERT C Coding Standard was created, and published in October 2008 as The CERT C Secure Coding Standard. CERT's Coding Standards continue to be widely adopted by industry. Cisco Systems, Inc., announced its adoption of the CERT C Secure Coding Standard as a baseline programming standard in its product development in October 2011 at Cisco's annual SecCon conference. Recently, Oracle has integrated all of CERT's secure coding standards into its existing Secure Coding Standards. This adoption is the most recent step of a long collaboration: CERT and Oracle previously worked together in authoring The CERT Oracle Secure Coding Standard for Java.

The CERT C Coding Standard continues to evolve. Existing guidelines are updated as new standards, such as Programming Languages--C, 3rd ed. (ISO/IEC 9899:2011), are introduced. Through large and small modifications--from changing a word in a rule title to writing new code examples--the guidelines continue to be improved by the ongoing activities of contributors. Obsolete guidelines are regularly culled from the wiki, and new rules and recommendations are added as technology and research warrant.

In 2013, a second snapshot of the CERT C Coding Standard was prepared for publication. The wiki had grown in the intervening five years: it now had 98 rules and 178 recommendations. We elected to publish only the rules, not the recommendations, in the second edition of The CERT C Coding Standard, published in April 2014. The rules laid forth in the new edition will help ensure that programmers' code fully complies with the new C11 standard; they also address earlier versions of the C Standard, including C99.

The CERT C Coding Standard itemizes coding errors that are the root causes of current software vulnerabilities in C, prioritizing them by severity, likelihood of exploitation, and remediation costs. Each rule includes examples of insecure code, as well as secure, C11-conforming, alternative implementations. If uniformly applied, these guidelines eliminate critical coding errors that lead to buffer overflows, format-string vulnerabilities, integer overflow, and other common vulnerabilities when programming in C.

The CERT C Coding Standard, second edition, covers all aspects of the new C Standard, including best solutions, compliant solutions, and pertinent language and library extensions. It also offers advice on issues ranging from tools and testing to risk assessment. Of the 98 rules, 42 are new--since the first edition, 30 rules have been deprecated, 30 more have been added, and a new section, Concurrency (containing 12 rules), has also been added.

A Tool for Developers

The Source Code Analysis Laboratory (SCALe) provides a means for developers to evaluate the conformance of their code to CERT's coding standards. CERT coding standards provide a normative set of rules against which software systems can be evaluated. Conforming software systems should demonstrate improvements in their safety, reliability, and security over nonconforming systems.

SCALe analyzes a developer's source code and provides a detailed report of findings to guide the code's repair. After the developer has addressed these findings and the SCALe team determines that the improved source code conforms to the standard, CERT issues the developer a certificate and lists the system in a registry of conforming systems.

Conformance to CERT coding standards requires that the source code not contain any rule violations. Occasionally, a developer may claim that code that appears to violate a rule actually is secure because of an exceptional condition. For example, library code with insufficient thread protection could still be secure when run only in single-threaded programs. If an exceptional condition is claimed, the exception must correspond to a predefined exceptional condition, and the application of this exception must be documented in the source code. Conformance with the recommendations is not necessary but, in many cases, will make it easier to conform to the rules and eliminate many potential sources of defects.

SCALe has also been used by the Department of Defense (DoD), which increasingly depends on networked software systems. One result of this dependency is an increase in attacks on both military and non-military systems, as attackers look to exploit these software vulnerabilities. Our technical report on this work, Supporting the Use of CERT Secure Coding Standards in DoD Acquisitions, provides guidance to help DoD acquisition programs address software security in acquisitions. It provides background on the development of secure coding standards, sample request for proposal (RFP) language, and a mapping of the Application Security and Development STIG to the CERT C Secure Coding Standard.

Since its inception, more than 20 SCALe analyses have been performed on a variety of systems from both government and industry for a variety of languages, including C, C++, Java, and Perl.

Addressing Challenges and Future Work

Coding standards are an integral part of the software development lifecycle and increasingly a requirement. The National Defense Authorization Act for FY13, Section 933, states "Improvements in Assurance of Computer Software Procured by the Department of Defense," requires evidence that government software development and maintenance organizations, including contractors, conform to DoD-approved secure coding standards during software development, upgrade, and maintenance activities, including through the use of inspection and appraisals. The Application Security and Development Security Technical Implementation Guide (STIG), Section 2.1.5, "Coding Standards," requires that program managers "ensure the development team follows a set of coding standards."

A number of challenges make compliance with these requirements difficult:

  • Secure coding standards must be developed for ubiquitous languages with no existing standards and, where possible, published by an international standards body to allow easy adoption by the DoD;
  • The number of actual rule violations discovered in conformance testing is excessive and must be reduced to levels that can be reasonably addressed by the development team;
  • It must be demonstrated that the adoption of secure coding standards will not degrade system performance and result in slow, bloated code.

To address these challenges in the coming year our work will focus on the following areas:

  • C++ Coding Standard. To address the lack of secure coding standards, we plan to complete the CERT C++ Secure Coding Standard. C++ is used extensively throughout the DoD including for major weapons systems such as the Joint Strike Fighter. Existing C++ coding standards fail to address security, subset the language, or are outdated and unprofessional.
  • Reduce Rule Violations by Enforcing Secure Coding Rules in Interactive Development Environments. To address the problem of excessive rule violations, we plan to collaborate with Clang developers and Japan Computer Emergency Response Team Coordination Center (JPCERT) to develop additional analyses for Clang's static analyzer to check for violations of a prioritized list of secure coding rules. Clang is an open-source compiler that has been integrated into Apple's XCode integrated development environment (IDE), which is the primary tool for developing software for iOS and OS X. Catching rule violations early will prevent these errors from propagating throughout the codebase and will allow developers to learn secure coding techniques while programming. New checkers will be submitted into the main trunk of Clang and integrated into XCode (as well as any other IDEs that support Clang integration), improving software security for all developers who use Clang.

    We will also collaborate with Dr. Bill Pugh, professor emeritus in the University of Maryland's Computer Science Department and FindBugs creator, to develop analysis against unchecked guidelines in The CERT Oracle Secure Coding Standard for Java and to integrate this analysis into Eclipse so that analysis results are immediately available to Android platform developers.
  • Demonstrate the Costs of Producing Secure Code. We are planning a research project with Igalia to evaluate the costs of producing a CERT-conforming implementation of the Chromium browser project. Igalia is a contributor to Chromium and a member of the World Wide Web Consortium (W3C). Chromium has several properties that make it a compelling demonstration: Chromium is an open-source project, released under a BSD-style license, and is the foundation for the Google Chrome browser. The performance of Chromium, which has a bug bounty program, is intensely scrutinized; developers are unlikely to accept patches that fix theoretical vulnerabilities but adversely affect performance. Chromium is used by hundreds of millions of users, and a successful case study will be widely publicized and replicated. This research will evaluate the effort required to discover and mitigate secure coding violations in the Chromium codebase. We will evaluate the performance, size, and resource consumption of the code before and after remediation and note common anti-patterns and mitigations.

In the long term, we hope to continue to develop and refine coding rules for existing secure coding standards, additional coverage for other languages and platforms, and additional analysis capabilities.

We welcome your feedback on our latest and future secure coding work. Please leave feedback in the comments section below.

Additional Resources

For more information about, The CERT C Coding Standard, Second Edition: 98 Rules for Developing Safe, Reliable, and Secure Systems, please visit
http://www.informit.com/store/cert-c-coding-standard-second-edition-98-rules-for-9780133805383.

To sign up for a free account on the CERT Secure Coding wiki, please visit
https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards.

To subscribe to our Secure Coding eNewsletter, please click here.

Get updates on our latest work.

Each week, our researchers write about the latest in software engineering, cybersecurity and artificial intelligence. Sign up to get the latest post sent to your inbox the day it's published.

Subscribe Get our RSS feed