Developers are focused on creating code for great products, usually under pressure to complete projects in increasingly tightened timescales and that can mean securing coding techniques take a backseat, writes Richard Bellairs, product marketing manager, Perforce Software.
However, the coding stage of software development is often the root cause of many security vulnerabilities. Hackers can exploit these vulnerabilities to change the behaviour of a system, preventing it from operating, or even insert malware or ransomware long after the product has shipped. It is even possible for malicious code to be intentionally introduced during the development process (for example, by a disgruntled developer).
While that is changing, – particularly in the era of DevOps, where there is far more awareness of the need to collaborate with other teams, continuously test and monitor application security, throughout the software lifecycle – applications are growing in complexity.
C++ is a commonly used programming language for demanding applications. It gives developers the flexibility needed to support greater innovation within complex projects. That’s the good news. The bad news is that this same flexibility also introduces more risk of coding errors. For example, with dynamic memory allocations, even experienced developers will inadvertently introduce memory leaks.
This is why, as part of efforts to make code more secure, the use of secure coding standards is on the rise. Typically designed and managed by industry consortia or associations, these coding standards pool the collective tried-and-tested experience from a group of expert contributors and sources. Some of the most common coding standards include CERT C/C++ (which aims to avoid security vulnerabilities); MISRA C/C++ (widely used in automotive and other safety critical markets, such as aerospace and medical device development) or AUTOSAR C++ Coding Guidelines (common in automotive and soon to be merged with MISRA).
Coding standards give developers and software engineering teams a set of guidelines or rules, in other words a framework against which they can check that code is ‘safe’ and so assist with ensuring software security. They are also used to help make sure that code is compliant with industry-specific safety and security standards.
Preventing Malicious Code
Here is an example of how a coding standard can prevent malicious code, taking buffer overflow – a common problem – and the coding standard CERT C/C++ as the examples. Buffer overflow happens when a program writes data outside the boundary of its allocated memory and this puts the software at risk because it becomes possible to inject malicious code into runtime memory.
That’s because if there is no check in place to ensure that the input buffer cannot overflow, a hacker can design an input or ‘payload’ containing malicious code, overflow the input buffer and overwrite the function’s return address with the malicious code. When the function returns, the program executes from the start of the malicious code. This may sound complicated but it is easily done.
However, within CERT C/C++, there is a coding rule that says ‘do not form or use out-of-bounds pointers or array subscripts’. It sounds like common sense, but ensuring this rule is followed will prevent this type of vulnerability. Another example is creation of uncontrolled format strings, which can allow ingress of malicious code by crashing the program, viewing the memory content or writing to an arbitrary memory location. Again, CERT has a rule for this: ‘exclude user input from format strings.’
These are just two examples of numerous vulnerabilities that coding standards can help prevent happening and also illustrate that coding standards are wonderfully simple in concept. They educate developers in what to do – or what not to do – giving them a ‘blueprint’ for best practice.
Implementing Coding Standards
Implementing coding standards is another matter. Back to the earlier statement about developers having enough pressures on their time: while coding standards give them confidence that they are writing safe and compliant programs, they really do not want another task on top of everything else. Plus, given the increasing scale and complexity of modern software development projects, keeping track of whether coding standards are being followed becomes impossible even if the will is there.
This is why most organisations adopting coding standards are also using tools that automate much of the process, such as static code analyzers. These constantly and thoroughly inspect every single line of code in background mode and deliver thousands of diagnostics right at the point of development. Any issues – whether deviation from a coding standard, excess complexity, or a hard-to-spot dataflow bug – are detected early, rather than at the more traditional stages of testing carried out by QA engineers at a later stage.
In this way, coding standards and static code analyzers become part of the whole ‘shift left’ movement, whereby developers take on some of the testing tasks, and complement the increasingly popularity of continuous testing throughout the development lifecycle. In turn, all of this can contribute towards successful DevOps. Static code analysis can also create a baseline for ‘best practice’ coding techniques and maintaining a consistent and high level of code quality within an organisation, ensuring that all developers – from newbies to seasoned professionals – are working to the same standard. ‘s
Ensuring code quality and adherence to industry standards are important benefits that together, coding standards and the tools used to implement them, can bring. However, in today’s increasingly sophisticated and connected world that inevitably expands the potential threat landscape, it is the prevention of the malicious code risk that is arguably the most important. We all know that security risks are multi-faceted and complex, but fixing as many vulnerabilities right at the start – in other words, the creation of code on which so much is based – needs to be a priority.