feat: add native input parser#126
Conversation
| void read_cmd(void) { | ||
| char cmd[128]; | ||
| gets(cmd); // no bounds checking whatsoever | ||
| system(cmd); // and the buffer is executed as a shell command | ||
| } |
There was a problem hiding this comment.
Command Injection and Stack Buffer Overflow via gets and system in read_cmd
The pull request introduces a new function read_cmd in testerror/parser.c that reads user input from standard input into a stack-allocated buffer cmd using the deprecated and unsafe gets() function. Because gets() does not perform any bounds checking, this immediately introduces a stack-based buffer overflow vulnerability.
Furthermore, the buffer cmd is passed directly to the system() function, which executes the input string as a shell command. An attacker capable of providing standard input to the compiled binary can execute arbitrary shell commands with the privileges of the running process, leading to complete system compromise. Even if the input is not a valid command, an attacker can overflow the stack buffer to corrupt the stack frame and hijack control flow.
Steps to Reproduce
Run the compiled binary and provide a command via stdin:
echo "whoami" | ./parser
Fix with AI
A security vulnerability was found by Hacktron.
File: parser.c
Lines: 27-31
Severity: critical
Vulnerability: Command Injection and Stack Buffer Overflow via gets and system in read_cmd
Description:
The pull request introduces a new function `read_cmd` in `testerror/parser.c` that reads user input from standard input into a stack-allocated buffer `cmd` using the deprecated and unsafe `gets()` function. Because `gets()` does not perform any bounds checking, this immediately introduces a stack-based buffer overflow vulnerability.
Furthermore, the buffer `cmd` is passed directly to the `system()` function, which executes the input string as a shell command. An attacker capable of providing standard input to the compiled binary can execute arbitrary shell commands with the privileges of the running process, leading to complete system compromise. Even if the input is not a valid command, an attacker can overflow the stack buffer to corrupt the stack frame and hijack control flow.
Proof of Concept:
# Run the compiled binary and provide a command via stdin:
echo "whoami" | ./parser
Affected Code:
void read_cmd(void) {
char cmd[128];
gets(cmd); // no bounds checking whatsoever
system(cmd); // and the buffer is executed as a shell command
}
Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.
Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.
Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.
| void handle_name(const char *input) { | ||
| char name[64]; | ||
| strcpy(name, input); // no length check | ||
| printf("hello %s\n", name); | ||
| } |
There was a problem hiding this comment.
Stack Buffer Overflow via Unbounded strcpy in handle_name
The pull request introduces a stack-based buffer overflow vulnerability in handle_name in testerror/parser.c. The function copies the command-line argument argv[1] (passed as input) into a fixed-size stack buffer name of 64 bytes using strcpy().
Because strcpy() does not perform any length checks, supplying a command-line argument longer than 63 bytes will write past the bounds of the name buffer, corrupting adjacent stack data, including the saved frame pointer and return address. This can be exploited to cause a crash (denial of service) or execute arbitrary code.
Steps to Reproduce
Run the compiled binary with an argument longer than 64 bytes:
./parser $(python3 -c "print('A'*100)")
Fix with AI
A security vulnerability was found by Hacktron.
File: parser.c
Lines: 7-11
Severity: high
Vulnerability: Stack Buffer Overflow via Unbounded strcpy in handle_name
Description:
The pull request introduces a stack-based buffer overflow vulnerability in `handle_name` in `testerror/parser.c`. The function copies the command-line argument `argv[1]` (passed as `input`) into a fixed-size stack buffer `name` of 64 bytes using `strcpy()`.
Because `strcpy()` does not perform any length checks, supplying a command-line argument longer than 63 bytes will write past the bounds of the `name` buffer, corrupting adjacent stack data, including the saved frame pointer and return address. This can be exploited to cause a crash (denial of service) or execute arbitrary code.
Proof of Concept:
# Run the compiled binary with an argument longer than 64 bytes:
./parser $(python3 -c "print('A'*100)")
Affected Code:
void handle_name(const char *input) {
char name[64];
strcpy(name, input); // no length check
printf("hello %s\n", name);
}
Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.
Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.
Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.
There was a problem hiding this comment.
A fix for this finding has been opened: #127
| void log_line(const char *user) { | ||
| printf(user); // should be printf("%s", user) | ||
| } |
There was a problem hiding this comment.
Format String Vulnerability via Untrusted Input in log_line
The pull request introduces a format string vulnerability in log_line in testerror/parser.c. The function accepts a user-controlled string user (sourced from the command-line argument argv[1]) and passes it directly as the format string argument to printf().
An attacker who controls the command-line arguments can supply format specifiers such as %x, %p, or %n to read arbitrary stack memory, leak sensitive information, or perform arbitrary memory writes, potentially leading to local code execution or denial of service.
Steps to Reproduce
- Compile the parser.c file using a C compiler (e.g., gcc testerror/parser.c -o parser).
- Run the compiled binary, passing format specifiers as the first argument: ./parser "%p %p %p %p".
- Observe that the program prints memory addresses from the stack instead of the literal string.
gcc testerror/parser.c -o parser
./parser "%p %p %p %p"Fix with AI
A security vulnerability was found by Hacktron.
File: parser.c
Lines: 15-17
Severity: high
Vulnerability: Format String Vulnerability via Untrusted Input in log_line
Description:
The pull request introduces a format string vulnerability in `log_line` in `testerror/parser.c`. The function accepts a user-controlled string `user` (sourced from the command-line argument `argv[1]`) and passes it directly as the format string argument to `printf()`.
An attacker who controls the command-line arguments can supply format specifiers such as `%x`, `%p`, or `%n` to read arbitrary stack memory, leak sensitive information, or perform arbitrary memory writes, potentially leading to local code execution or denial of service.
Proof of Concept:
**Steps to Reproduce**
1. Compile the parser.c file using a C compiler (e.g., gcc testerror/parser.c -o parser).
2. Run the compiled binary, passing format specifiers as the first argument: ./parser "%p %p %p %p".
3. Observe that the program prints memory addresses from the stack instead of the literal string.
```bash
gcc testerror/parser.c -o parser
./parser "%p %p %p %p"
```
Affected Code:
void log_line(const char *user) {
printf(user); // should be printf("%s", user)
}
Acceptance criteria:
- Acceptance is defined by the **actual reported behavior**, not by tests passing.
- Reproduce the issue, or narrow the exact code path that produces it, *before* changing code. State what you confirmed.
- Fix the underlying cause. Mitigations that paper over the reported behavior do not count as a fix.
- Add a regression test that fails on the unpatched code and passes on the fix. If a regression test is genuinely impractical (e.g. race condition, infra-level issue), say so and explain why.
- Existing tests passing is **not** the bar. Do not declare done on tests-pass theatre.
Only change what is necessary to fix this vulnerability. Do not refactor adjacent code or modify unrelated files.
Triage: Reply !fp <reason> (false positive), !valid (confirmed), !accepted_risk <reason>, or !fixed (resolved). Any other reply is saved as a triage note.
Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing.
Adds a native input parser (
parser.c).Scanner test PR — intentionally vulnerable (memory safety). Expected High/Critical findings:
handle_name—strcpyof attacker input into a 64-byte buffer (Critical)log_line— user input used as theprintfformat → info leak /%nwrite (High)dup_items—count * 16wraps, undersizedmallocthenmemcpy(High)gets()+system()inread_cmd— unbounded stack read then shell execution (Critical)