Skip to main content

C and C++

Vulkro reads C and C++ source with a set of dedicated detectors and a short-range taint pass. It finds dangerous call shapes and proves a small set of input-to-sink flows. It is not a memory-safety verifier, and it reads no C or C++ package manager.

C and C++ are covered by vulkro (Core). Salesforce code is covered by the separate vulkro-sf binary.

vulkro scan .
vulkro scan . --all-confidence # also show the low-confidence leads

What is analysed​

AreaCoverage
Project detectionA .c / .h file or a Makefile, CMakeLists.txt, configure or *.mk (C); a C++ source or header file (C++)
Files readC: .c, .h. C++: .cpp, .cc, .cxx, .c++, .hpp, .hh, .hxx, .h++, .ipp, .inl, .tcc. A .h file is read as C
Taint sourcesargv, getenv, read / recv / fread / getline, fgets, the scanf family
Taint sinksprintf-family format strings, system / popen / exec*, a tainted length into memcpy / memmove / strncpy / strncat / bcopy with a fixed-size local array as the destination, file paths for fopen / open, allocation sizes
Taint rangeWithin one function, plus one call into a uniquely named project function
C++Every C detector and the taint pass also run on C++ files, plus six C++ rules
Endpoints and authNot analysed
DependenciesNone: no Conan, vcpkg or other C/C++ package manager is read

Detectors​

RuleWhat it findsCWE
C-BAN-001gets, strcpy, strcat, sprintf, vsprintf676
C-SCANF-001scanf %s / %[ with no field width120
C-FMT-001A non-literal printf-family format string134
C-CMDI-001, C-EXEC-001system / popen with a non-constant command; exec* launching a shell78
C-TLS-001TLS certificate verification turned off295
C-XXE-001libxml2 parsing with external entities enabled611
C-RAND-001rand for security values, predictable seeds338
C-TMP-001mktemp, tmpnam, tempnam377
C-PERM-001World-writable file or directory modes732
C-SETUID-001An unchecked setuid / setgid return252
C-ALLOC-001An unchecked multiplication in an allocation size190
C-STRNCPY-001strncpy / strncat that may leave no terminating null170
C-SIG-001A non-async-signal-safe call inside a signal handler364
C-CRED-001, C-KEY-001A secret compared with a literal; a hardcoded crypto key or IV798, 321
C-UAF-001, C-DF-001Use after free and double free in the same block416, 415
CPP-SMARTPTR-001, CPP-DANGLE-001delete of a smart pointer's .get(); returning the address of a local416, 562
CPP-MOVE-001, CPP-CAST-001Use of a moved-from object; reinterpret_cast825, 843
CPP-FMT-001, CPP-VCALL-001std::vformat / fmt::runtime format strings; a virtual call in a constructor or destructor134, 665

Hidden by default as low-confidence leads (shown with --all-confidence): C-MEM-001 (non-constant copy length), C-NULLDEREF-001 (unchecked malloc dereference), C-UNINIT-001 (uninitialized local read), C-TOCTOU-001 (check-then-use on a path) and C-ALLOCA-001 (runtime-sized stack allocation).

The taint pass reports under c-taint-format-string, c-taint-command, c-taint-buffer-overflow, c-taint-path and c-taint-alloc-size. Secrets, IaC and container checks run on a C or C++ repository as on any other.

Example​

void log_message(void) {
char *msg = getenv("APP_MESSAGE");
printf(msg);
}

vulkro scan . reports an uncontrolled format string (CWE-134) on the printf line, with a trace from getenv to the sink. A finding with a trace is reported as proven.

Limits​

  • No memory-safety proof. There is no bounds, value-range or symbolic analysis. The use-after-free, double-free, null and uninitialized-read rules are same-block pattern checks, not proofs, and out-of-bounds access in general is not detected.
  • Short range. Taint is followed inside one function, plus one call into a project function with a single definition. A path that crosses that call is demoted below the default confidence floor, and allocation sizes are not followed across it.
  • No preprocessor. Source is parsed as written: a sink hidden behind a macro is not seen, and both sides of an #if / #else are read.
  • No C++ types. There is no type resolution, template instantiation or overload resolution, so lifetime bugs such as a dangling string_view are out of reach. There are no C++-specific taint sources (such as std::cin).
  • No endpoint map, no auth model, no dependency CVEs.

See Supported languages for how C and C++ compare with the other languages.