VNX-277: Insecure Inherited Permissions
Detects permission sets that everything created afterwards inherits and that let anyone write: a process umask that leaves others-write open (umask(0), os.umask(0), process.umask(0), shell or Dockerfile umask 000, systemd UMask=0000), a Windows NULL DACL, an inheritable SDDL allow ACE for Everyone, and a .NET FileSystemAccessRule/RegistryAccessRule granting Everyone or Users write with inheritance.
| Field | Value |
|---|---|
| Rule ID | VNX-277 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C, C++, Python, Go, PHP, Ruby, JavaScript / TypeScript, Rust, Shell, Dockerfile, C# |
| CWE | CWE-277 |
| 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 | inherited-permissions umask acl file-permissions cwe-277 |
| Source | internal/sast/rules/vnx-277.rego |
Overview
VNX-277 maps to CWE-277: Insecure Inherited Permissions. Some permission settings are not applied to one object but inherited by every object created after them. If that inherited set is too broad, every file, directory, pipe or registry key the program creates is too broad as well, including those created by libraries and child processes that never asked for it.
Reported:
- A umask that leaves others-write open.
umask(0),umask(0000),umask(020)in C and C++,os.umask(0)and python-daemonDaemonContext(umask=0o000)in Python,libc::umask(0), nixumask(Mode::empty())and aDaemonizebuilder’s.umask(0o000)in Rust,syscall.Umask(0)/unix.Umask(0)in Go,umask(0)in PHP,File.umask(0)in Ruby,process.umask(0)/process.umask("0000")in Node.js,umask 000/umask 0/umask a=rwxin shell scripts and DockerfileRUNlines, andUMask=0000in a systemd unit. Libraries create files with mode0666and directories with0777and rely on the umask to remove group and other write; with a zero umask they become world-writable. - A Windows NULL DACL.
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE)grants everyone full access to whatever is created with that descriptor. - An inheritable SDDL ACE for a broad group. An allow ACE with
OI/CIthat gives Everyone (WD), Anonymous (AN), Authenticated Users (AU) or Users (BU) generic all or write rights, such asD:(A;OICI;GA;;;WD). - A .NET access rule inherited by children.
new FileSystemAccessRule(...)ornew RegistryAccessRule(...)that allows Everyone, Users, Authenticated Users or the World SIDFullControl,Modifyor write rights withContainerInherit/ObjectInherit.
What Gets Flagged
setsid();
umask(0); // FLAGGED: everything the daemon creates later inherits it
chdir("/");
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); // FLAGGED: NULL DACL
// FLAGGED: Everyone gets FullControl on the directory and everything below it
security.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, AccessControlType.Allow));
umask 000 # FLAGGED
[Service]
UMask=0000 # FLAGGED: every file the service creates is world-writable
What Is Not Flagged
- A umask that masks others-write:
022,027,077,002. - Reading the umask (
old = os.umask(0); os.umask(old),$mask = umask();), and a zero umask restored within a few statements, to the saved value or to a closing literal (umask(0); mkfifo(p, 0620); umask(022);), such as around anos.open(path, flags, 0o600)in atry/finally: that sets one exact mode on purpose and leaves nothing behind. - A umask taken from a variable, a real DACL (
SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE)), ACEs for SYSTEM or Administrators, read-only or non-inheritable rules, and deny rules. - Test code and the calls in comments or strings.
Remediation
umask(027); /* or 077 for private data */
var rule = new FileSystemAccessRule(serviceAccountSid, FileSystemRights.Modify,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, AccessControlType.Allow);
Build a security descriptor that names the principals that need access instead of passing a NULL DACL.
References
- CWE-277: Insecure Inherited Permissions
- umask(2)
- Null DACLs and Empty DACLs
- Security Descriptor String Format
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-277
// nosec vnx-277
Or record an ignore rule: vulnetix ignore add --rule vnx-277 --reason "...". See Suppressing findings.