VNX-663: Use of a Non-reentrant Function in a Concurrent Context
Reports Java static fields of non-thread-safe types (SimpleDateFormat, DecimalFormat, MessageDigest, Cipher, Mac, Matcher...) and C/C++ calls to static-buffer libc functions (strtok, localtime, gmtime, getpwuid, gethostbyname...) in files that start threads.
| Field | Value |
|---|---|
| Rule ID | VNX-663 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Java, C, C++ |
| CWE | CWE-663 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | concurrency thread-safety reentrancy cwe-663 |
| Source | internal/sast/rules/vnx-663.rego |
Overview
VNX-663 maps to CWE-663: Use of a Non-reentrant Function in a Concurrent Context.
- Java: a
staticfield of typeSimpleDateFormat,DateFormat,DecimalFormat,NumberFormat,MessageFormat,ChoiceFormat,MessageDigest,Mac,Cipher,Signatureorjava.util.regex.Matcher, shared by every thread. - C/C++: a call to
strtok,localtime,gmtime,ctime,asctime,getpwnam,getpwuid,getgrnam,getgrgid,gethostbyname,gethostbyaddr,getservbyname,getlogin,ttyname,strsignal,ecvt,fcvt,cryptorinet_ntoa(also asstd::) in a file that starts threads (pthread_create,std::thread/std::jthread,std::async,CreateThread,_beginthreadex,#pragma omp).
Not reported: ThreadLocal holders, DateTimeFormatter and Pattern (thread-safe), local and instance formatters, a static formatter the same file locks with synchronized (NAME) or uses only inside synchronized methods, the _r variants, member calls and lookalike names, declarations that share a libc name, files that start no threads (a thread marker in a comment does not count), comments and string literals.
Why This Matters
Two threads formatting with one SimpleDateFormat corrupt its internal Calendar and return wrong dates or throw. strtok and localtime keep their state in a static buffer, so one thread’s call silently overwrites another’s result.
What Gets Flagged
private static final SimpleDateFormat ISO = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // FLAGGED
private static MessageDigest sha256; // FLAGGED
char *tok = strtok(line, ","); /* FLAGGED: file calls pthread_create */
struct tm *t = localtime(&now); /* FLAGGED */
Remediation
- Java: use
java.time.format.DateTimeFormatter, aThreadLocal, or a new instance per call (MessageDigest.getInstanceis cheap). - C/C++: use
strtok_r,localtime_r,gmtime_r,getpwuid_r,getaddrinfo/inet_ntop.
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-663
// nosec vnx-663
Or record an ignore rule: vulnetix ignore add --rule vnx-663 --reason "...". See Suppressing findings.