We're all familiar with hackers probing Web applications to find construction or operation vulnerabilities. One popular method used to exploit such flaws is to inject code into the running application, a process common in SQL injections and cross-site scripting attacks. A more sophisticated injection creates a buffer overflow that forces a program to run an attacker's written code.
Taking advantage of the build process
Modern software applications are complex and comprised of many different components. To speed up their development, creators build most software from a combination of pre-written source code and third-party components. After all, why spend weeks reinventing a program feature when it can be quickly found and integrated into an application, especially now that many such components are open source and -- via the GNU General Public License -- can be obtained for free?
To further accelerate development, simplify project management and reduce application build time, modern compilers permit developers to include dependency information within a project's settings. Dependency information allows the application to be built in an automated fashion by retrieving pre-determined components from the appropriate repositories. Maven, for example, is a popular and widely used build system that handles dependency management and multi-project relationships. Maven and other similar tools, like Ant and Ivy, help developers handle huge amounts of code. Such management leads to the problem of cross-build injection.
For one, the attacker can compromise the server that hosts the components and replace them with malicious copies. Alternatively, malware creators can compromise the DNS server of the build machine, redirecting requests to a machine controlled by the attacker. Either method works because developers and their tools do not question the source or integrity of the code they are using. Most Internet users know not to open email attachments from unknown sources, yet software developers regularly download code and incorporate it into their applications without reviewing exactly what it does. The dangers of this practice are magnified when a build process is set up to automatically retrieve code from the Internet.
Raising the stakes
The integrity of applications built in this way depend on the security of the sites hosting open source components. Applications also rely on the network infrastructure used to locate them. The safest way to avoid cross-build injection attacks is to not use automated tools that incorporate dependency resolution. If such a practice is not feasible, then development teams must create their own internal repository, along with a strictly enforced policy to control how new code or components are added to it. These regulations should include a review to ensure that the code is safe and fit for purpose. To mitigate DNS compromises, the server hosting the repository should only be referred to by its IP address.
Should cross-build injection attacks become widespread, they would undermine the open source movement and the growing acceptance of open source software. When a program is compromised at the point of creation, there is no limit to the malicious actions that it can carry out. Looking ahead, I think we will see more use of digitally signed code and build tools that incorporate signature checking, both of which can ensure that code is coming from a known source and has not been tampered with in any way.
About the author:
Michael Cobb, CISSP-ISSAP is the founder and managing director of Cobweb Applications Ltd., a consultancy that offers IT training and support in data security and analysis. He co-authored the book IIS Security and has written numerous technical articles for leading IT publications. Mike is the guest instructor for several SearchSecurity.com Security Schools and, as a SearchSecurity.com site expert, answers user questions on application security and platform security.