Building a secure high assurance web server with 300 lines of code
Editor’s Note: Excerpted from their book Embedded Systems Security, the authors demonstrate what is required to build, with 300 lines of state machine code, a secure web server program that is the equivalent of the popular commercial open source Apache server with about 200, 000 lines of code.
In 2008, Green Hills Software developed a high-assurance web server (HAWS) to host a website immune to hackers. HAWS was deployed as an application on the high-assurance, security- certified INTEGRITY embedded real-time operating system technology.
The web server’s lead designer was Dan Hettena, senior operating systems, security, and virtualization architect at Green Hills Software.
Why did Green Hills decide to write a web server from scratch instead of attempting to lock down a commercial web server such as Apache?
Apache is a tremendously powerful and successful open source web server, hosting a majority of the world’s websites as of the time of this writing. But the reason for not adopting Apache in this particular case is that the value of resources to be managed and protected by the web portal was considered extremely high, and the threat of sophisticated attackers wishing to subvert or deface the web portal was also considered extremely high.
This combination of high-value resources exposed to a high-threat environment requires high assurance in security that cannot be feasibly retrofitted to software not originally developed to meet this standard.
The Apache code base consists of hundreds of thousands of lines of code developed using commercial general-purpose processes, not using a high-assurance security standard.
Hundreds of software vulnerabilities have been found in Apache over the years, and the probability of severe, undiscovered vulnerabilities in any snapshot of the software is considered extremely high. One example of vulnerability from the U.S. CERT National Vulnerability Database is as follows:
CVE-2010-0425: “modules/arch/win32/mod_isapi.c in mod_isapi in the Apache HTTP Server does not ensure that processing is complete before calling isapi_unload.which allows remote attackers to execute arbitrary code via unspecified vectors related to a crafted request.”
The primary security policies of HAWS are to ensure that the web portal’s content cannot be maliciously corrupted and that requests from legitimate clients not be denied service by other (malicious) clients.
Physical security of the web server’s computer, as well as upstream network quality of service, is beyond the scope of the HAWS design goals (although these issues were addressed at the system level).
In addition to these stringent integrity and availability policies, HAWS was designed to handle many thousands of concurrent connections with good response time performance. It is important to note that Apache is a perfectly good choice for most systems (and in fact a port has been done to the same INTEGRITY operating system hosting HAWS), but a higher level of security was deemed necessary for this particular application.
A Minimal Implementation
In contrast to a typical commercial web server’s hundreds of thousands of lines of code, the HAWS web services engine consists of approximately 300 lines of code versus about 200,000 for the Apache.
This feat was accomplished primarily by converting the sophisticated logic of parsing and responding to HTTP requests into a simple state machine that operates on a pre-loaded, read-only database of information corresponding to a particular instance of the hosted files serviced by HAWS.
The central state machine loop is shown in the following code listing (code comments and macros elided). Readers are not expected to understand the code; it is provided to demonstrate an example of a minimal implementation:
It is left as an exercise for readers to browse the open source Apache code, comparing the preceding state-machine-driven implementation with a traditional input parsing loaded with gobs of special case logic.
However, be warned: the Apache software dealing with HTTP- compliant input handling and response consists of thousands of lines of code. By avoiding common parsing mechanisms, including large network read operations and string matching, HAWS avoids the kinds of runtime logic that is prone to vulnerability (e.g., buffer overflows).
Finally, the availability features of HAWS are implemented with simple policies instead of complicated heuristics. Nevertheless, these policies serve their purpose well; HAWS has proven impervious to sophisticated penetration testing and has not encountered unscheduled downtime or reported service unavailability since its deployment in 2008.