VNX-283: Unverified Ownership
Detects C/C++ code that trusts a file because its permission bits for group/others are tight (st_mode & S_IWOTH, & 077, std::filesystem perms::others_*) without ever comparing st_uid with the expected owner.
| Field | Value |
|---|---|
| Rule ID | VNX-283 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-283 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | unverified-ownership file-permissions cwe-283 |
| Source | internal/sast/rules/vnx-283.rego |
Overview
VNX-283 maps to CWE-283: Unverified Ownership. Programs that load keys, configuration or plugins often refuse a file that group or others can read or write. That check is only half of the test: a file with mode 0600 that belongs to another user still passes, and that user controls what the program loads. OpenSSH, sudo and similar tools check the owner as well as the mode.
The rule reports a mode test against group/other bits (st_mode & S_IWOTH, S_IWGRP, S_IRWXG, S_IRWXO, S_IROTH, S_IRGRP, or an octal mask such as 022, 077, 0002; in C++ also std::filesystem permissions() against perms::group_*/perms::others_*) with no st_uid comparison within 25 lines.
What Gets Flagged
struct stat st;
if (stat(path, &st) != 0) return -1;
if (st.st_mode & (S_IRWXG | S_IRWXO)) { /* FLAGGED: owner never checked */
return -1;
}
return read_key(path);
return (info.st_mode & 022) == 0; // FLAGGED
What Is Not Flagged
- A check that also compares
st_uid(withgetuid(),geteuid(),0or a looked-up user). - Executable-bit and file-type tests (
S_IXUSR,S_ISREG) and copying a mode (st_mode & 07777). - Comments and string literals.
Ownership verified in a different function is not visible to this rule.
Remediation
Open the file once, fstat() the descriptor, and check owner and mode together:
int fd = open(path, O_RDONLY | O_NOFOLLOW);
struct stat st;
if (fd < 0 || fstat(fd, &st) != 0) return -1;
if (st.st_uid != geteuid() && st.st_uid != 0) return -1;
if (st.st_mode & (S_IRWXG | S_IRWXO)) return -1;
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-283
// nosec vnx-283
Or record an ignore rule: vulnetix ignore add --rule vnx-283 --reason "...". See Suppressing findings.