How to Prevent Malicious Code (Plus Examples)
Cybersecurity risks are everywhere today. And the threat of a cyberattack is high. There are many forms of cyberattacks. Many of these can be caused by malicious code.
What Is Malicious Code?
Malicious code (malcode) is any code that causes harm.
This code could:
- Access private data.
- Change the behavior of a system.
- Prevent the system from operating.
How Malicious Code Happens
Malicious code could be intentionally written into a system. For example, a disgruntled developer might write malicious code on purpose.
Or malicious code could be injected after development. For example, malware, spyware, or ransomware gets into the system after it’s deployed and causes harm. This is a very real concern, particularly for teams developing safety-critical systems.
It’s best to prevent malicious code before it can compromise your program.
Security best practices should be adopted early in the development process. This is the best way to keep your software safe from malicious code vulnerabilities.
How to Prevent Malicious Code Vulnerabilities (Examples)
You can protect your software from malicious code. And that’s by making sure it doesn’t contain security vulnerabilities.
Here’s how to prevent malicious code.
1. Use Secure Coding Standards
— such as CERT C/C++ — are designed to prevent security vulnerabilities.
CERT, for instance, targets code with undefined behavior that could lead to a security risk.
Example 1: Buffer Overflow
Buffer overflow is a well-known security vulnerability. It occurs when a program writes data outside the boundary of its allocated memory.
This compromises the security of the software because it may be possible to inject malicious code into runtime memory.
Even commonly used library functions — such as gets() or fscanf() — can lead to buffer overflow when not used carefully.
Why Buffer Overflow Leaves Code Vulnerable
Buffer overflow leaves your code vulnerable.
Here’s an example.
If the program is receiving data — without a check in place to ensure that the input buffer can’t overflow —then it will be possible to design an input, or “payload’, that contains malicious code. This input can overflow the input buffer.
As a result, it overwrites the function’s return address with the address of the malicious code. When the function returns, the program executes from the start of the malicious code.
How to Prevent Buffer Overflow
CERT is an example of a C coding rule that helps prevent buffer overflow. This rule also applies in CERT C++.
“Do not form or use out-of-bounds pointers or array subscripts.”
By applying this rule, you’ll avoid writing to out-of-range pointers or array subscripts. And this prevents the execution of arbitrary code.
MISRA C also has a rule for this — and CWE notes a similar weakness.
Example 2: Uncontrolled Format String
Uncontrolled format string is another security vulnerability.
It exists when a call is made to a formatted I/O function with a format string containing unsanitized data from an untrusted, external source. This is often referred to as “tainted” data.
Why Uncontrolled Format String Leaves Code Vulnerable
An uncontrolled format string leaves your code vulnerable.
It can allow an attacker to potentially enable the execution malicious code by:
- Crashing the program.
- Viewing memory content.
- Writing to an arbitrary memory location.
Check out an example from CERT >>
How to Prevent Uncontrolled Format String
Be careful when using functions that take a format string as an argument. Example functions include fprintf(), sprintf(), and snprintf().
CERT is an example of a C coding rule that prevents format string attacks. This rule also applies in CERT C++.
“Exclude user input from format strings.”
Make sure that untrusted input is not used as part of a format string.
Example 3: Signed Integer Overflow
Signed integer overflow is another common security exploit. Overflow occurs when the result of an arithmetic operation is too large to be stored in the underlying representation of the integer.
In C and C++ programming, integer overflow can lead to buffer overflow if it goes undetected.
Why Signed Integer Overflow Leaves Your Code Vulnerable
Integer overflow results in undefined behavior, so it’s important to ensure that operations on integers do not result in overflow.
In the worst case scenario, integer overflow can lead to buffer overflows — and the execution of malicious code by an attacker.
Check out some examples from CERT >>
How to Prevent Signed Integer Overflow
CERT is an example of a coding rule that prevents integer overflow. This rule also applies in CERT C++.
“Ensure that operations on signed integers do not result in overflow.”
Integer overflows can be prevented. You can do this by implementing suitable range checks on incoming function parameters.
2. Enforce Secure Coding Rules With a Static Code Analyzer
The best way to enforce secure coding rules is to use a static analyzer.
A static code analyzer checks code against a set of coding rules, such as those in CERT C/C++, automatically. The best static analyzers — like — include additional rules to ensure best practice coding.
For instance, Helix QAC makes it easy to check code against the CERT coding rules mentioned above. And it delivers thousands of diagnostics to improve your code before testing begins — and before security vulnerabilities can compromise your software.
By ensuring these rules are followed, you’ll avoid serious coding errors — and potential malicious code vulnerabilities.