VNX-708: Incorrect Ownership Assignment
Reports chown(), lchown(), fchown() and fchownat() calls in C and C++ whose path, uid or gid comes from the command line or the environment, directly or through one or two assignments a few lines above, unless a condition validates the value first.
| Field | Value |
|---|---|
| Rule ID | VNX-708 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-708 |
| 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 | incorrect-ownership-assignment chown cwe-708 |
| Source | internal/sast/rules/vnx-708.rego |
Overview
VNX-708 maps to CWE-708: Incorrect Ownership Assignment. It reports a chown(), lchown(), fchown() or fchownat() call whose path, uid or gid argument comes from argv[...], optarg or getenv()/secure_getenv(). The value can be used in the call itself, assigned to a variable up to 20 lines above (atoi(argv[2]), strtoul(optarg, ...)), or passed through one more assignment (getpwnam(name) and then pw->pw_uid). The rule reads a call that spans several lines up to three lines past its first line.
Why This Matters
When the caller chooses the owner, a file can end up owned by an account outside the program’s control sphere. In a setuid or root helper it is worse: the caller can pick an arbitrary path and take ownership of it.
What Gets Flagged
uid_t uid = (uid_t)atoi(argv[2]);
gid_t gid = (gid_t)atoi(argv[3]);
if (chown(argv[1], uid, gid) != 0) // FLAGGED
struct passwd *pw = getpwnam(user); // user = optarg
return fchown(fd, pw->pw_uid, pw->pw_gid); // FLAGGED
The rule does not report owners that are constants, getuid()/getgid(), or values copied from stat() of another file. It also skips ops->chown(...) style function pointers, test code, comments and string literals. It does not follow flows through other functions or files.
Remediation
- Take the owner from the program’s own trusted configuration, not from the caller.
- If a user must be named, check the name against an allow-list, and refuse root and system accounts.
- In a privileged program, open the target with
O_NOFOLLOWand usefchown()on the descriptor once you have checked the path.
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-708
// nosec vnx-708
Or record an ignore rule: vulnetix ignore add --rule vnx-708 --reason "...". See Suppressing findings.