Skip to content

Commit 2c6d8cb

Browse files
committed
feat(cpp): Add Insecure Functions query
1 parent f4bd333 commit 2c6d8cb

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Use of Insecure Functions
2+
3+
## Description
4+
5+
Insecure functions are those that can lead to vulnerabilities in the code, such as buffer overflows, format string vulnerabilities, or other security issues.
6+
These functions may not perform adequate input validation or may allow for unsafe operations.
7+
8+
## Examples
9+
10+
### Insecure Function Usage
11+
12+
```cpp
13+
#include <cstdio>
14+
#include <cstring>
15+
16+
void vulnerable_examples() {
17+
char buffer[50];
18+
char source[100] = "This is a very long string that will overflow the buffer";
19+
20+
// 1. strcpy - No bounds checking, can cause buffer overflow
21+
strcpy(buffer, source); // VULNERABLE: source may be longer than buffer
22+
23+
// 2. strcat - No bounds checking for concatenation
24+
char dest[10] = "Hello";
25+
strcat(dest, " World!"); // VULNERABLE: may overflow dest buffer
26+
27+
// 3. sprintf - Can cause buffer overflow with format strings
28+
char formatted[20];
29+
sprintf(formatted, "User: %s, ID: %d", "VeryLongUsername", 12345); // VULNERABLE
30+
31+
// 4. gets - Reads unlimited input, always vulnerable
32+
char input[100];
33+
gets(input); // VULNERABLE: no bounds checking whatsoever
34+
35+
// 5. scanf with %s - No bounds checking
36+
char name[20];
37+
scanf("%s", name); // VULNERABLE: user can input more than 20 characters
38+
39+
// 6. sscanf with %s - Similar vulnerability as scanf
40+
char data[30];
41+
char line[] = "VeryLongStringThatExceedsBufferSize";
42+
sscanf(line, "%s", data); // VULNERABLE: no bounds checking
43+
}
44+
```
45+
46+
### Secure Function Usage
47+
48+
```cpp
49+
#include <cstdio>
50+
#include <cstring>
51+
#include <string>
52+
53+
void secure_examples() {
54+
char buffer[50];
55+
char source[100] = "This is a very long string that will overflow the buffer";
56+
57+
// 1. Use strncpy instead of strcpy
58+
strncpy(buffer, source, sizeof(buffer) - 1);
59+
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null termination
60+
61+
// Alternative: Use std::string (C++)
62+
std::string safe_string = source;
63+
64+
// 2. Use strncat instead of strcat
65+
char dest[20] = "Hello";
66+
strncat(dest, " World!", sizeof(dest) - strlen(dest) - 1);
67+
68+
// Alternative: Use std::string concatenation
69+
std::string safe_dest = "Hello";
70+
safe_dest += " World!";
71+
72+
// 3. Use snprintf instead of sprintf
73+
char formatted[50];
74+
int result = snprintf(formatted, sizeof(formatted), "User: %s, ID: %d", "Username", 12345);
75+
if (result >= sizeof(formatted)) {
76+
// Handle truncation
77+
printf("Warning: Output was truncated\n");
78+
}
79+
80+
// 4. Use fgets instead of gets
81+
char input[100];
82+
if (fgets(input, sizeof(input), stdin) != NULL) {
83+
// Remove newline if present
84+
size_t len = strlen(input);
85+
if (len > 0 && input[len-1] == '\n') {
86+
input[len-1] = '\0';
87+
}
88+
}
89+
90+
// Alternative: Use std::getline (C++)
91+
std::string safe_input;
92+
std::getline(std::cin, safe_input);
93+
94+
// 5. Use scanf with field width specifier
95+
char name[20];
96+
scanf("%19s", name); // Limit input to 19 characters + null terminator
97+
98+
// Better alternative: Use fgets
99+
if (fgets(name, sizeof(name), stdin) != NULL) {
100+
// Remove newline if present
101+
size_t len = strlen(name);
102+
if (len > 0 && name[len-1] == '\n') {
103+
name[len-1] = '\0';
104+
}
105+
}
106+
107+
// 6. Use sscanf with field width specifier
108+
char data[30];
109+
char line[] = "VeryLongStringThatExceedsBufferSize";
110+
sscanf(line, "%29s", data); // Limit to 29 characters + null terminator
111+
}
112+
113+
// Modern C++ approach using safe containers
114+
void modern_cpp_approach() {
115+
// Use std::string for dynamic strings
116+
std::string user_input;
117+
std::getline(std::cin, user_input);
118+
119+
// Use std::vector for dynamic arrays
120+
std::vector<char> buffer(100);
121+
122+
// Use standard library algorithms
123+
std::string source = "Hello";
124+
std::string dest = "World";
125+
std::string result = source + " " + dest; // Safe concatenation
126+
}
127+
```
128+
129+
## Common Vulnerability Patterns
130+
131+
1. **Buffer Overflows**: Functions like `strcpy`, `strcat`, and `sprintf` don't check buffer boundaries
132+
2. **Format String Vulnerabilities**: Using user input directly in format strings
133+
3. **Unbounded Input**: Functions like `gets` and `scanf("%s", ...)` can read unlimited input
134+
4. **Missing Null Termination**: Functions like `strncpy` may not null-terminate strings
135+
136+
## Best Practices
137+
138+
- Always use bounded versions of string functions (`strncpy`, `strncat`, `snprintf`)
139+
- Specify field widths when using `scanf` family functions
140+
- Consider using C++ `std::string` and containers for automatic memory management
141+
- Validate input lengths before processing
142+
- Always null-terminate strings when using bounded functions
143+
- Use static analysis tools like CodeQL to identify these patterns automatically
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @name Insecure Functions
3+
* @description This query identifies the use of insecure functions in C++ code, such as `strcpy`, `strcat`, and `sprintf`, which can lead to buffer overflows and other vulnerabilities.
4+
* @id cpp/security/insecure-functions
5+
* @kind problem
6+
* @problem.severity warning
7+
* @security-severity 1.0
8+
* @sub-severity low
9+
* @precision high
10+
*/
11+
12+
import cpp
13+
import ghsl
14+
15+
predicate isInsecureFunction(FunctionCall call, string functionName) {
16+
functionName = call.getTarget().getName() and
17+
functionName in ["strcpy", "strcat", "sprintf", "gets", "scanf", "sscanf"]
18+
}
19+
20+
from FunctionCall call, string functionName
21+
where isInsecureFunction(call, functionName)
22+
select call, "Insecure function '" + functionName + "' used. Consider using safer alternatives"

0 commit comments

Comments
 (0)