Static Analysis for Secure C code#
Security rules in static analysis focus on identifying vulnerabilities and enforcing coding practices that enhance the security of software systems. These rules are particularly critical in embedded systems and safety-critical environments, where exploits can lead to severe consequences. Below are some key security-focused static analysis rules, examples, and best practices.
Buffer Overflows#
Rule: Avoid reading/writing outside buffer boundaries.
Example (Non-compliant):
char buffer[10];
strcpy(buffer, “This string is too long for the buffer”); // Overflow
Compliant:
char buffer[10];
strncpy(buffer, “Short”, sizeof(buffer) - 1); // Use safe functions
buffer[sizeof(buffer) - 1] = ‘\0’; // Null-terminate
Null Pointer Dereferences#
Rule: Always check pointers before dereferencing them.
Example (Non-compliant):
int *ptr = NULL;
*ptr = 10; // Dereferencing a null pointer
Compliant:
int *ptr = NULL;
if (ptr != NULL) {
*ptr = 10;
}
Injection Attacks#
Rule: Validate all input to prevent injection vulnerabilities.
Example (Non-compliant):
char query[256];
sprintf(query, “SELECT * FROM users WHERE id = ‘%s’”, user_input); // SQL Injection risk
Compliant:
char query[256];
snprintf(query, sizeof(query), “SELECT * FROM users WHERE id = ?”); // Use parameterized queries
Unchecked Return Values#
Rule: Always verify the return values of functions, especially system calls.
Example (Non-compliant):
FILE *file = fopen(“example.txt”, “r”);
fread(buffer, sizeof(buffer), 1, file); // Ignoring return value
Compliant:
FILE *file = fopen(“example.txt”, “r”);
if (file != NULL) {
if (fread(buffer, sizeof(buffer), 1, file) != 1) {
// Handle read error
}
fclose(file);
}
Avoid Hardcoded Credentials#
Rule: Do not embed sensitive data directly in the code.
Example (Non-compliant):
char *password = “SuperSecret123”; // Hardcoded credential
Compliant:
char password[128];
// Retrieve password securely, e.g., from environment variables or secure storage
Proper Memory Management#
Rule: Avoid use-after-free and double-free vulnerabilities.
Example (Non-compliant):
int *ptr = malloc(sizeof(int));
free(ptr);
free(ptr); // Double-free
Compliant:
int *ptr = malloc(sizeof(int));
free(ptr);
ptr = NULL; // Nullify pointer after free
Cryptographic Best Practices#
Rule: Use strong encryption and avoid weak algorithms.
Example (Non-compliant):
// Using outdated algorithm
DES_encrypt(data, key, output);
Compliant:
// Use modern cryptographic libraries
AES_encrypt(data, key, output);
Avoid Format String Vulnerabilities#
Rule: Do not allow user-controlled data in format strings.
Example (Non-compliant):
printf(user_input); // User-controlled format string
Compliant:
printf(“%s”, user_input); // Specify format explicitly
Use Secure Functions#
Rule: Avoid functions prone to vulnerabilities (e.g., gets, strcpy).
Example (Non-compliant):
char input[100];
gets(input); // Unsafe function
Compliant:
char input[100];
fgets(input, sizeof(input), stdin); // Use safer alternatives
Avoid Race Conditions#
Rule: Ensure proper synchronization in multi-threaded programs.
Example (Non-compliant):
if (access(“file.txt”, F_OK) == 0) {
// File may be deleted/modified by another thread/process
open(“file.txt”, O_RDONLY);
}
Compliant:
int fd = open(“file.txt”, O_CREAT | O_EXCL, 0644); // Atomic operation
if (fd != -1) {
// File access ensured
close(fd);
}
Avoid Information Leakage#
Rule: Do not log sensitive data.
Example (Non-compliant):
printf(“Password: %s\n”, password); // Exposing sensitive data
Compliant:
printf(“Password processing complete.\n”); // Generalized message
Secure Default Configurations#
Rule: Ensure secure default settings in the code.
Example (Non-compliant):
int allow_remote_access = 1; // Insecure default
Compliant:
int allow_remote_access = 0; // Secure default
Integration into Static Analysis Tools#
Static analysis tools like Coverity, CodeSonar, or Fortify can be configured to enforce these security rules. Key features include:
Vulnerability Detection: Identifying code patterns associated with security risks.
Custom Rules: Creating project-specific rules for unique requirements.
Industry Standards Compliance: Ensuring adherence to OWASP, CERT C, or other security frameworks.
By applying these security rules, you can minimize vulnerabilities and improve the robustness of your embedded or general software systems.